Lombok
gradle dependency
1
2
3
4
5
dependencies {
...
compileOnly 'org.projectlombok:lombok:1.18.20'
annotationProcessor 'org.projectlombok:lombok:1.18.20'
}
장점
boilerplate code를 작성하는데 드는 시간.비용 절감
코드가 깔끔해진다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Data
public class MyCandlestick {
private double high;
private double low;
private double open;
private double close;
private double volume;
private long date;
}
@Data annotation을 사용함으로서, 모든 필드에 getter,setter를 추가할수 있다.
opensource라 비용을 지불할 필요가없다.
2009년부터 지금까지 사용되고있는 신뢰할수 있는 라이브러리이다.
단점
lombok으로 작성된 코드를 vanilla java code로 변환하는것이 원활하지 않을때가 있다. (변환툴이 완벽하지 않다.)
IDE plugin이 필요하다.
가장 큰단점은 lombok에 의해서 생성된 코드가 javadocs에 나타나지 않는다.
Annotation
Required Args Constructor
초기화 되지 않은 final 필드나, @NotNull이 붙은 필드에 대해 생성자를 생성해줌.
1
2
3
4
5
6
7
8
9
@Service
@RequiredArgsConstructor
public class RequiredArgsConstructorDIServiceExample {
private final FirstRepository firstRepository;
private final SecondRepository secondRepository;
private final ThirdRepository thirdRepository;
// ...
}
class파일을 확인해보면 다음과 같이 되어있다.
1
2
3
4
5
6
7
8
9
@Service
public class RequiredArgsConstructorDIServiceExample {
@ConstructorProperties({"firstRepository", "secondRepository", "thirdRepository"})
public RequiredArgsConstructorDIServiceExample(FirstRepository firstRepository, SecondRepository secondRepository, ThirdRepository thirdRepository) {
this.firstRepository = firstRepository;
this.secondRepository = secondRepository;
this.thirdRepository = thirdRepository;
}
}
@AllArgsConstructor
모든 필드 값을 파라미터로 받는 생성자를 만들어 준다.
@NoArgsConstructor
파라미터가 없는 기본 생성자 생성
@EqualsAndHashCode
- equals : 두 객체의 내용이 같은지, 동등성(Equality)을 비교하는 연산자
- hashcode : 두 객체가 같은 객체인지, 동일성(Identity)를 비교하는 연산자
@EqualsAndHashCode어노테이션을 사용하면 자동으로 이 메소드를 생성할 수 있다.
@EqualsAndHashCode(callSuper = true) 로 설정시 부모 클래스 필드 값들도 동일한지 체크하며, false(기본값)일 경우 자신 클래스의 필드 값만 고려한다.
@Data
@Getter,@Setter,@RequiredArgsConstructor,@ToString,@EqualsAndHashCode를 한번에 설정해주는 어노테이션이다.
@NonNull
1
2
3
4
5
6
7
8
9
10
import lombok.NonNull;
public class NonNullExample extends Something {
private String name;
public NonNullExample(@NonNull Person person) {
super("Hello");
this.name = person.getName();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
import lombok.NonNull;
public class NonNullExample extends Something {
private String name;
public NonNullExample(@NonNull Person person) {
super("Hello");
if (person == null) {
throw new NullPointerException("person is marked @NonNull but is null");
}
this.name = person.getName();
}
}
위의 코드는 아래코드와 같다. 즉, @NonNull annotation은 if (param == null) throw new NullPointerException("param is marked @NonNull but is null");
를 삽입해준다.
@Builder
사용가능한 use case
1. 클래스를 객체화하기 위해서 빌더를 사용하고 싶을때
1
2
3
4
5
6
@Getter
@Builder
public class Widget {
private final String name;
private final int id;
}
1
2
3
4
5
6
7
8
9
Widget testWidget = Widget.builder()
.name("foo")
.id(1)
.build();
assertThat(testWidget.getName())
.isEqualTo("foo");
assertThat(testWidget.getId())
.isEqualTo(1);
2. 객체의 복사본을 생성하고 싶은경우
1
2
3
4
@Builder(toBuilder = true)
public class Widget {
//...
}
1
2
3
4
5
6
7
8
9
10
11
12
Widget testWidget = Widget.builder()
.name("foo")
.id(1)
.build();
Widget.WidgetBuilder widgetBuilder = testWidget.toBuilder();
Widget newWidget = widgetBuilder.id(2).build();
assertThat(newWidget.getName())
.isEqualTo("foo");
assertThat(newWidget.getId())
.isEqualTo(2);
3. builder에 required fields를 명시하고 싶은 경우
1
2
3
4
5
6
7
8
9
10
@Builder(builderMethodName = "internalBuilder")
public class RequiredFieldAnnotation {
@NonNull
private String name;
private String description;
public static RequiredFieldAnnotationBuilder builder(String name) {
return internalBuilder().name(name);
}
}
1
RequiredField.builder("NameField").description("Field Description").build();
4. 수정과 상속이 불가능한 클래스를 builder로 객체화 하고 싶은 경우
1
2
3
4
5
@Value
final class ImmutableClient {
private int id;
private String name;
}
1
2
3
4
5
6
7
class ClientBuilder {
@Builder(builderMethodName = "builder")
public static ImmutableClient newClient(int id, String name) {
return new ImmutableClient(id, name);
}
}
1
2
3
4
5
6
7
8
ImmutableClient testImmutableClient = ClientBuilder.builder()
.name("foo")
.id(1)
.build();
assertThat(testImmutableClient.getName())
.isEqualTo("foo");
assertThat(testImmutableClient.getId())
.isEqualTo(1);