Lombok이 무엇인지 간단히 살펴보고 넘어가자. 어떻게 프로젝트에 적용하는지는 언급하지 않는다. 검색을 통해서 알아보자.
가장 기본적인 기능으로 Lombok은 getter/setter method를 만들어 준다.
예를 들어 아래와 같이 User라는 모델 객체가 있다고 가정하자.
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
|
@Data
public class User {
private String name;
private int age;
}
|
Lombok을 적용하면 우측 코드처럼 간단히 모델 객체를 선언할 수 있다.
@Builder
Lombok에는 @Builder Annotation도 있다. 이는 모델 객체를 생성할 때 Builder를 자동으로 추가해 주는 Annotation이다. 이를 이용하면 Builder Pattern을 아주 손쉽게 적용할 수 있다.
아래 예제를 살펴보자.
public class User {
private String name;
private int age;
public static UserBuilder builder() {
return new UserBuilder();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//Builder Class
public class UserBuilder {
private String name;
private int age;
public User build() {
User user = new User();
user.setName(this.name);
user.setAge(this.age);
return user;
}
public UserBuilder name(String name) {
this.name = name;
return this;
}
public UserBuilder age(int age) {
this.age = age;
return this;
}
}
|
@Data
@Builder
public class User {
private String name;
private int age;
}
|
public class UserBuilderTest {
@Test public void builderTest() {
User user = User.builder()
.name("홍길동")
.age(19)
.build();
System.out.println(user);
}
}
|
public class UserBuilderTest {
@Test public void builderTest() {
User user = User.builder()
.name("홍길동")
.age(19)
.build();
System.out.println(user);
}
}
|
우측 코드는 Lombok의 Builder를 적용한 코드이다.
코드를 확 줄여준 것을 볼 수 있다.
@Builder 사용시 특정 속성에 기본값을 설정하려면???
이 글을 쓰게된 주된 목적은 여기부터이다.
@Data@Builderpublic class User {
private String name;
private int age = 19;
}
|
public class UserBuilderTest {
@Test public void builderTest() {
User user = User.builder()
.name("홍길동")
.build();
System.out.println(user);
}
}
|
테스트 코드에서 user.getAge()는 19일 것으로 기대했다.
하지만 결과는…
왜 그럴까? 어떻게 age에 19라는 기본값을 지정할 수 있을까?
구글링을 해보니 기본 생성자(default constructor)를 만들어 기본값을 지정하라는 코맨트가 많았다.
Lombok을 사용하는데, 기본 생성자를 매번 생성해 하고 싶지 않아 좀 더 찾아보기로 했다.
결론은 1.16.16 버전 이상을 사용하면 @Builder.Default 라는 Annotation이 추가 되었다.
(불행히도 위 궁금증을 가질 때 1.16.6 버전을 사용하고 있었다.)
Lombok을 1.16.16으로 업그레이드 이후 테스트를 해 보았다.
@Data@Builderpublic class User {
private String name;
@Builder.Default private int age = 19;
}
|
public class UserBuilderTest {
@Test public void builderTest() {
User user = User.builder()
.name("홍길동")
.build();
System.out.println(user);
}
}
|
이제 정상적으로 age에 19라는 값이 설정되는 것을 확인할 수 있다.
그렇다면 Lombok 1.16.16 이전 버전에서는 기본값이 적용되지 않았을까?
Lombok 공신문서에서 @Builder.Default에 대해서 아래와 같이 설명하고 있다.
@Builder.DefaultIf a certain field/parameter is never set during a build session, then it always gets 0 / null / false. If you've put @Builder on a class (and not a method or constructor) you can instead specify the default directly on the field, and annotate the field with @Builder.Default:
@Builder.Default private final long created = System.currentTimeMillis();
|
즉, @Builder를 사용한 경우 build()시 설정하지 않으면 0 / null / false가 된다고 언급하고 있다.
위 테스트 코드에서 getAge() 했을 때, 0이 나온 이유이다.
결론
Lombok의 @Data, @Builder를 적극적으로 사용하자. 개발의 편의성을 위해…
그리고 특정 속성에 기본값을 지정하고 싶을 때에는 @Builder.Default를 사용하자.(단 Lombok 1.16.16 이상)
현재 최신 버전이 1.16.16이다.(at 2017/04/12)
참고
'Programing > Java' 카테고리의 다른 글
Jackson을 이용하여 JSON -> POJO 변환시 POJO에 존재하지 않는 property가 있는 경우 (0) | 2017.07.21 |
---|---|
상속 구조의 모델 객체에서 Lombok의 @Builder, @Delegate 사용기 (0) | 2017.04.21 |
HashMap, Hashtable, ConcurrentHashMap 동기화 처리 방식 (0) | 2016.12.20 |
HashMap, TreeMap 그리고 LinkedHashMap의 차이 (1) | 2016.12.19 |
ConnectionTimeout과 SocketTimeout의 차이 (0) | 2016.11.18 |