들어가며
@Builder를 이용하면서, 빌더를 통해 생성되지 않는 필드의 값에는 자동적으로 Null이 담기게 됩니다. 따라서, 필드의 기본값을 설정해주면 좋을 것 같아서 찾아보니, @Builder.Default를 사용해보면 좋을 것 같아 적용했으나…
아래와 같은 경고가 떴습니다.
warning: @Builder.Default requires @Builder or @SuperBuilder on the class for it to mean anything.
아이쿠 바보.. @Builder의 사용법에 대해 정리를 한 번 해야 겠다😓라는 생각이 들었습니다.
따라서, 이 글은 @Builder의 사용 방법에 대해 소개합니다!!
이전 글)
@Builder와 @SuperBuilder를 가볍게 훑어보고 싶다면,
❏ @Builder 사용 방법
@Builder는 클래스 위에서도, 생성자 위에서도 사용될 수 있는데요, 하나씩 살펴봅시다.
1. 클래스
@Getter
@Builder
public class Person {
private String name;
private int age;
}
- 클래스 전체 필드를 빌더로 사용할 수 있습니다.
2. 생성자
@Getter
public class Person {
private String name;
private int age;
private String job;
@Builder
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
- 생성자 필드에 해당하는 것만 빌더로 사용할 수 있습니다. (name, age만 가능, job은 어떻게 될까? 조금 뒤에 설명!)
사용 예시)
Person person = Person.builder()
.name("홍길동")
.age(20)
.build();
정리하자면 클래스의 전체 필드를 빌더로 생성하고 싶다면, 클래스 위에 @Builder를,
특정 필드만 가지고 빌더로 생성하고 싶다면, 생성자 위에 @Builder를 배치하면 됩니다! 👍
❏ @Builder.Default란
@Getter
@Builder
public class Person {
private String name;
private int age;
private String job;
}
// 객체 생성
Person person = Person.builder()
.name("홍길동")
.age(20)
.build();
빌더를 통해서, name과 age 필드만 설정을 해준다면 job은 어떻게 될까요?
명시적으로 설정하지 않은 필드들에는 기본값으로 Null 들어가게 됩니다.
따라서 이러한 특징 때문에, 반드시 초기화가 필요한 필드에서는 @Builder.Default를 이용하여 초기화를 해주면 됩니다.
사용 예시)
@Getter
@Builder
public class Person {
private String name;
private int age;
@Builder.Default
private String job = "job";
}
❓ 저는 특정 필드에만 접근할 수 있도록 생성자를 사용해서 @Builder.Default를 사용하면 오류가 나요
아주 간단한 해결방법. 생성자 내에서 기본값을 할당해주는 방법을 사용해주면 됩니다!
@Getter
public class Person {
private String name;
private int age;
private String job;
@Builder
public Person(String name, int age) {
this.name = name;
this.age = age;
this.job = "job" // 기본값
}
}
개인적으로 저는 이 방법을 통해 기본값을 할당해주던 와중에, @Builder.Default를 알게 되어 한번 적용해보고 싶었습니다.
warning: @Builder.Default requires @Builder or @SuperBuilder on the class for it to mean anything.
@Builder.Default는 맨 처음 보여드렸던 오류 문구처럼 반드시 @Builder나 @SuperBuilder가 클래스위에 존재해야 합니다.
저는 생성자 위에 @Builder를 사용하고 있었기에 해당 방법은 옳지 않았던 방식이구나를 알게 되었습니다.
❏ 추가적인 @Builder 사용법
❍ @Singular
@Getter
@Builder
public class Person {
private String name;
private int age;
private String job;
@Singular
private List<String> hobbies;
}
@Singular는 hobbies처럼 컬렉션 타입인 필드가 존재할 때, 해당 필드에 대해서 값을 하나씩 추가가 가능하도록 합니다.
사용 예시)
Person person = Person.builder()
.name("홍길동")
.hobby("독서")
.hobby("코딩")
.build();
hobbies처럼 복수형으로 필드명을 설정해주니, hobby로 하나씩 값을 추가할 수 있도록 변수명이 설정되는 것이 신기하더라구요.
Can't singularize this name: "hobby"; please specify the singular explicitly (i.e. @Singular("sheep"))
복수형이 아닌 경우에는 이렇게 오류가 나는데, 보시다시피 @Singular("sheep") 처럼 지정해주면 오류가 사라집니다.
❍ @Builder(toBuilder = true)
@Builder(toBuilder = true)
public class Person {
private String name;
private int age;
}
@Builder 어노테이션에는 toBuilder라는 속성을 지정할 수 있습니다.
해당 속성은 이미 생성된 기존의 인스턴스를 기반으로 새로운 인스턴스를 생성할 수 있도록 합니다.
사용 예시)
Person person1 = Person.builder()
.name("홍길동")
.age(30)
.build();
log.debug(person1.toString)
// Person(name=홍길동, age=30)
Person person2 = person1.toBuilder()
.age(31)
.build();
log.debug(person2.toString)
// Person(name=홍길동, age=31)
이처럼 @Builder를 활용하면, 객체 생성을 가독성 좋게! 유연하게! 할 수 있습니다.
toBuilder 외에도 여러 속성이 존재하는데, 여유가 생긴다면 정리해보는 것으로 하고 여기서 마치겠습니다.
이렇게 간단하게 정리해본 @Builder 사용법에 대해 마치면서,,,
다음 글도 읽어봐주시면 감사하겠습니다.
@Builder와 @SuperBuilder 그리고.. @NoArgsConstructor