인생은 속도가 아니라 방향이다

[JAVA] Lombok @Getter, @Setter, @EqualsAndHashCode, @Data 자주쓰이는 어노테이션들 본문

백엔드(Back-end)/Java

[JAVA] Lombok @Getter, @Setter, @EqualsAndHashCode, @Data 자주쓰이는 어노테이션들

기록하는 동구 2020. 10. 20. 14:03
반응형

 안녕하세요, 고졸개발자 동구입니다. Java로 개발하다보면 일일이 생성자, 접근자 만들어주기 코드량도 많아지고 불편할텐데요. 그런점들을 해결해주는 자바 라이브러리중 하나인 Lombok에 자주쓰이는 어노테이션들을 소개해드릴게요! 

 

@Getter , @Setter (접근자/설정자 생성)

 

1
2
3
4
5
6
7
public class TestVO {
    
    @Getter @Setter
    private String name;
    private String tel;
}
 
cs

 

이제부터 일일이 get메소드와 set메소드를 하나씩 쓸필요없이 위와 같이 한 필드레벨에서만 접근자/설정자를 생성할수도 있습니다.

혹은 여러 필드가 존재한다면?

 

 

1
2
3
4
5
6
7
8
@Getter
@Setter
public class TestVO {
 
    private String name;
    private String tel;
}
 
cs

 

위와 같이 클래스레벨에서 모든필드에 적용되는 접근자/설정자를 생성할수있습니다. 참 쉽고 간단하죠?

 

 


 @ToString (ToString 메소드  생성)

 

 

이제는 @ToString에대해서 알아 보겠습니다. @toString 어노테이션을 이용하면 일일이 toString()메소드를 만들어줄 필요는 없습니다.

 

 

1
2
3
4
5
6
7
8

@Getter
@Setter
@ToString
public class MemberVO {

 
    private String id;
    private String password;
    private String name;
    private String tel;
}
cs

 

 

 

자, 위와 같이 MemberVO클래스를 만들어 보겠습니다. 준비가 됬다면, 출력해볼까요?

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    @Test
    public void ToString_테스트() {
        
        MemberVO member = new MemberVO();
        
        //member set
        member.setId("id");
        member.setName("name");
        member.setPassword("password");
        member.setTel("tel");
        
 

//출력 결과

// member - MemberVO(id=id, name=name, password=password tel=tel)

    }
cs

 

 

toString 메소드를 만들지않아도 다음과 같이 콘솔에 출력되는걸 알수있습니다.

 

 

여기에 굳이 toString()으로 출력하고싶지않은 필드값이 존재한다면, exclude를 사용하시면 됩니다.

 

※주의할점※

@ToString 의 경우 무척이나 편리하지만 JPA를 이용하는 경우에는 원하는 속성들만 출력되도록 조정할 필요가 많습니다. 꼭 exclude 속성을 이용해서 원하지 않는 속성을 출력하지 않도록 제어해보시면 좋을것 같습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
@Getter
@Setter
@ToString(exclude = {"password""id"})
public class MemberVO {
 
    private String id;
    private String password;
    private String name;
    private String tel;
}
 
cs

 

 

위와같이 exclude 설정을 하고 출력하게되면 아래와 같이 출력됩니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    @Test
    public void ToString_테스트() {
        
        MemberVO member = new MemberVO();
        
        //member set
        member.setId("id");
        member.setName("name");
        member.setPassword("password");
        member.setTel("tel");
        
        
        log.info("member - {}", member);
        //출력 결과
//        member - MemberVO(name=name, tel=tel)
    }
    
cs

 

 

 


@NoArgsConstructor , @RequiredArgsConstructor,  @AllArgsConstructor (생성자 생성)

 

 

이번에는 생성자를 자동으로 생성해주는 lombok 어노테이션을 알아보겠습니다.  총 3가지 입니다.

 

@NoArgsConstructor - 파라미터가 없는 생성자를 생성합니다.

@RequiredArgsConstructor - final 이나 @NonNull인 필드 값만 파라미터로 받는 생성자를 만들어 줍니다.

@AllArgsConstructor - 모든 필드 값을 파라미터로 받는 생성자를 만들어줍니다.

 

 

 

아래와 같이 3개의 어노테이션을 적어두고 테스트를 진행해보겠습니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
@NoArgsConstructor
@RequiredArgsConstructor
@AllArgsConstructor
public class TestVO {
    @NonNull
    private String id;
    @NonNull
    private String password;
    private String name;
    private String tel;
}
 
cs

 

 

어노테이션을 붙인 클래스가 준비가 됬다면 생성자를 각각생성하고 출력해보겠습니다.

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    @Test
    public void 테스트() {
        
        //@NoArgsConstructor
        TestVO test1 = new TestVO();
        log.info("test1 : {}", test1);
        //@RequiredArgsConstructor
        TestVO test2 = new TestVO("id""password");
        log.info("test2 : {}", test2);
        //@AllArgsConstructor
        TestVO test3 = new TestVO("id""password","1","2");

        log.info("test3 : {}", test3);

//출력결과

// test1 : TestVO(id=null, password=null, name=null, tel=null)

// test2 : TestVO(id=id, password=password, name=null, tel=null)

// test3 : TestVO(id=id, password=password, name=1, tel=2)

        
    }
cs

 

 

결과가 잘 출력되는걸 볼수있습니다.

 


 

④ @EqualsAndHashCode (equals, hashCode  생성)

@EqualsAndHashCode 어노테이션은  equals와 hashcode를 자동으로 생성해주는 어노테이션 입니다. @ToString 어노테이션과 마찬가지로 exclude 파라미터로 필드를 제외하거나 callSuper 파라미터로 부모 객체를 생략하거나 포함할수있습니다.

 

Java에서 equals와 hascode는 다음과 같은 의미입니다.

equals : 두 객체의 내용이 같은지, 동등성(equality)를 비교하는 연산자입니다.
hashcode : 두 객체가 같은 객체인지, 동일성(identity)를 비교하는 연산자입니다.

 

 

먼저 첫번째로, exclude 파라미터를 알아보겠습니다. 각각 2개의 클래스를 만들고, 한곳은 exclude 적용, 다른 한곳은 exclude을 적용하지 않겠습니다.

 

아래 exclude = "value1" 는 value1는 동등비교에 포함시키지 않겠다는 의미입니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@EqualsAndHashCode(exclude = "value1")
@Setter
public class Lombok1   {
 
    private String value1;
    private String value2 = "value2";
}
 
@EqualsAndHashCode
@Setter
public class Lombok2   {
 
    private String value1;
    private String value2 = "value2";
}
 
cs

 

@Test 어노테이션을 써서 테스트 코드를 아래와같이 작성합니다.  

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   @Test // 첫번째 테스트
    public void EqualsAndHashCode_Test() {
        
        Lombok1 test1 = new Lombok1();
        test1.setValue1("서로 다른 값1");
        log.info("test1 HashCode - {}", test1.hashCode()); // -564885323
        
        Lombok1 test2 = new Lombok1();
        test2.setValue1("서로 다른 값2");
        log.info("test2 HashCode - {}", test2.hashCode()); // -564885323
        
        log.info("result - {}", test1.equals(test2)); // result - true
        
    }
    
   @Test // 두번째 테스트
    public void EqualsAndHashCode_Test2() {
        
        Lombok2 test1 = new Lombok2();
        test1.setValue1("서로 다른 값1");
        log.info("test1 HashCode - {}", test1.hashCode()); // 1031504354
 
        Lombok2 test2 = new Lombok2();
        test2.setValue1("서로 다른 값2");
        log.info("test2 HashCode - {}", test2.hashCode()); // 1031504354
        
        log.info("result - {}", test1.equals(test2)); // result - false
        
    }
 
cs

 

 

첫번째 테스트에서는 value1에 서로다른값들을 넣어주고 동등비교했을때 value1을 exclude 해줬기에 결과값이 true로 나옵니다.

 

두번째 테스트에서는 exclude를 적용하지 않았기에 false로 결과값이 나옵니다!

 

두번째로는 of 파라미터를 알아보겠습니다.  

@EqualsAndHashCode(of="id"): 연관 관계가 복잡해 질 때, @EqualsAndHashCode에서 서로 다른 연관 관계를 순환 참조하느라 무한 루프가 발생하고, 결국 stack overflow가 발생할 수 있기 때문에 id 값만 주로 사용합니다.

 


⑤ @Data (위의 대부분의 것들을 합친 것!)

@Data 어노테이션은 @ToString, @EqualsAndHashCode, @Getter, @Setter, @RequiredArgsConstructor 의 한 묶음입니다.

 

 

※주의할점

하나의 어노테이션으로 많은 메소드를 자동으로 생성되기때문에 편리한것이 사실이지만, ORM(Object Relational Mapping) 객체관계매핑에서 주의해야합니다.

 

ORM은 객체와 객체가 관계를 가지는 조합의 형태로, 테이블 간의 연간관계를 표현합니다. 단, 이런 경우에는 부모객체와 자식객체의 toString()에서 문제가 생기게 됩니다. 서로 무한 반복 호출이 진행되면서 StackOverflow를 유발할수있으므로 가능한 몇라인이 길어지더라도 @Getter, @Setter, @ToString 따로사용하는게 좋습니다.

 

 

 

참고 :

velog.io/@jayjay28/%EC%9E%90%EC%A3%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-Lombok-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98

 

스타트스프링부트 - 구멍가게 코딩단

반응형
Comments