@Getter, @Setter
: 말그대로 getter, setter method를 생성해주는 놈이야!
AccessLevel을 명시해줌으로써 접근제한자를 지정 해 줄 수 있어.
1 | public Class Sample { |
( setter의 경우 실무에서 무분별하게 사용할 경우 후에 의도치 않은 값의 변경으로 인한 어려움을 겪을 수 있기에 상황에 맞춰서 필요할 때만 사용할 것..)
@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
: 모두 생성자 생성과 관련된 놈이야
@NoArgsConstructor
: 파라미터가 없는 생성자를 생성해줘.
이를 이용해 @NoargsConstructor(AccessLevel.PROTECTED) 이렇게 사용할 경우 만약 모든 필드에 대한 값이 들어가야함을 보장하고 싶을 때 기본 생성자 호출을 막음으로써 이후에 발생할 수 있는 문제를 사전에 차단할 수 있어.
@RequiredArgConstructor
: 초기화 되지 않은 모든 final 필드, @NonNULL로 마크되어있는 필드들에 대한 생성자를 자동으로 생성해줘. (파라미터의 순서는 클래스에 있는 필드 순서에 맞춰서 생성자가 생성)
@AllArgsConstructor
: 클래스에 존재하는 모든 필드에 대한 생성자를 자동으로 생성해줘.
👏👏👏 주의 사항 👏👏👏
@RequiredArgsConstructor와 @AllArgsConstructor는 사용을 지양하는 것이 좋아!!
why?? 위의 두 어노테이션을 통해 생성된 생성자는 클래스의 필드 순서에 맞게 생성 된다고 하였지.
1 |
|
위의 이러한 코드가 있다고 가정 해 보자. 이후 생각을 해보니 attr1 과 attr2의 순서를 바꾸는 것이 가시성 측면에서 좋다고 생각이 들어 그 위치를 변경하였다.
1 |
|
이런식으로 말이닷! 그럼 어떻게 될까?? 둘의 타입은 동일하기에 컴파일 시에
1 | Sample sample = new Sample(100, 200); |
이 코드에 있어 에러가 발생하지는 않을 것이다. 하지만 초기에 의도했던 attr1에 100, attr2에 200이 아닌 attr1에 200, attr2에 100이 들어가는 상황이 발생하게 되는 것이다. 이러한 상황이 발생할 수 있는 가능성을 제거하고자 사용을 지양한다.
그럼 어떻게 작성하는 것이 좋냐!?
@Builder를 사용하는 것을 권장해
1 | public static class Sample { |
- @Builder를 클래스에 붙일 경우 모든 속성에 대해 지정가능
- 생성자에 붙이는 경우는 모든 속성에 대해 원치 않고 특정 필드에 대해 원할 경우 특정 필드의 값을 채워주는 생성자에 어노테이션을 붙임으로써 사용가능
- 생성자 메소드에도 사용가능
- @Singular를 collection에 지정해줌으로써 빌더패턴에서 컬렉션에 하나씩 값을 추가하게 끔 할 수 있어.
@EqualsAndHashCode
: equals, hashCode를 자동생성 해줘
- equals : 두 객체의 내용이 같은지 동등성을 비교
- hashCode : 두 객체가 같은 객체인지 동일성을 비교
- callSuper 속성을 통해 메소드 자동 생성 시 부모 클래스의 필드까지 고려할지의 여부를 결정할 수 있어(default : false 자신 클래스 값만 고려)
👏👏👏 주의 사항 👏👏👏
변경가능한(Mutable) 객체에 아무런 파라미터 없이 그냥 사용할 경우 문제가 발생할 수 있어. 주의해야할 부분은 아래와 같아.
1 |
|
위처럼 동일한 객체임에도 set에 저장 후 필드 값을 변경하면 hashCode가 변경되면서 찾을 수가 없게 되어버려.
→ 그래서!!
- 불변(Immutable) 클래스를 제외하고는 아무 파라미터 없는 @EqualsAndHashCode사용은 지양하자
- @EqualsAndHashCode(of={“field”}) 형태로 동등성 비교에 필요한 필드를 명시하는 형태로 사용하자!
@Data
: @Getter, @Setter, @RequiredArgsConstructor, @ToString, @EqualsAndHashCode 를 한번에 설정해주는 애야!!
→ 위에서 지양한다는 어노테이션이 포함된 것을 보니 해당 어노테이션도 지양해야할 것이 보이쥐
@NonNull
: 필드에 지정해주면 Null을 check 해줘! 만약 null값이 들어오면 NPE 발생시켜.
@ToString
: toString() 메소드를 대체하는 어노테이션으로 callSuper 속성을 통해 상속받은 클래스의 정보까지 출력여부를 결정할 수 있다.
@Value
: @Data와 비슷하지만 불변으로 만들어준다고 생각하면 될 것 같애. private 접근제어자와 final이 붙은 상수가 되거등. 기본 생성자를 만들어주나 private이야.
@Wither
: 이 어노테이션도 불변과 관련된 녀석인데 원하는 프로퍼티를 다시 할당할 때 해당 Object의 필드를 변경하는 것이 아니라 원하는 값으로 필드를 셋팅한 새로운 Object를 뱉어내줘.
1 | public class witherSample { |