반응형
이제 Lombok의 끝자락으로 왔습니다.
2탄에서는 단일 클래스에서 @SuperBuilder를 사용하였을 시에 어떻게 되는지 확인하였습니다. 앞서 말씀드렸다시피 상속을 사용하여 객체에 @Builder를 사용하였을 시에 문제가 발생하였는데, @SuperBuilder는 어떻게 생겨먹었길래 오류가 해소되는지 한번 소스를 확인해 봅니다.
물론, 앞의 소스를 통해서 "아~ 이렇게 되는구나. 그럼 상속 시에는 이렇게 되겠네?"라고 하시는 분들도 계실 겁니다. 그러나, 예측과 실제 보는 부분은 다른 것이므로 직접 확인해 봅니다.
주석을 통한 @SuperBuilder를 사용한 원 소스는 다음과 같습니다.
// Person 클래스
package com.example.builder.entity;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@AllArgsConstructor
@NoArgsConstructor
@SuperBuilder
public class Person {
private Long id;
private String name;
private int age;
}
// Student 클래스
package com.example.builder.entity;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class Student extends Person {
private String schoolName;
private String schoolYear;
}
그럼 원래의 소스가 어떻게 풀어져서 나왔는지 확인해 봅시다.
// Person 클래스
package com.example.builder.entity;
public class Person {
private Long id;
private String name;
private int age;
protected Person(final PersonBuilder<?, ?> b) {
this.id = b.id;
this.name = b.name;
this.age = b.age;
}
public static PersonBuilder<?, ?> builder() {
return new PersonBuilderImpl();
}
public Person(final Long id, final String name, final int age) {
this.id = id;
this.name = name;
this.age = age;
}
public Person() {
}
public abstract static class PersonBuilder<C extends Person, B extends PersonBuilder<C, B>> {
private Long id;
private String name;
private int age;
public PersonBuilder() {
}
public B id(final Long id) {
this.id = id;
return this.self();
}
public B name(final String name) {
this.name = name;
return this.self();
}
public B age(final int age) {
this.age = age;
return this.self();
}
protected abstract B self();
public abstract C build();
public String toString() {
return "Person.PersonBuilder(id=" + this.id + ", name=" + this.name + ", age=" + this.age + ")";
}
}
private static final class PersonBuilderImpl extends PersonBuilder<Person, PersonBuilderImpl> {
private PersonBuilderImpl() {
}
protected PersonBuilderImpl self() {
return this;
}
public Person build() {
return new Person(this);
}
}
}
// Student 클래스
package com.example.builder.entity;
public class Student extends Person {
private String schoolName;
private String schoolYear;
protected Student(final StudentBuilder<?, ?> b) {
super(b);
this.schoolName = b.schoolName;
this.schoolYear = b.schoolYear;
}
public static StudentBuilder<?, ?> builder() {
return new StudentBuilderImpl();
}
public Student() {
}
public Student(final String schoolName, final String schoolYear) {
this.schoolName = schoolName;
this.schoolYear = schoolYear;
}
public abstract static class StudentBuilder<C extends Student, B extends StudentBuilder<C, B>> extends Person.PersonBuilder<C, B> {
private String schoolName;
private String schoolYear;
public StudentBuilder() {
}
public B schoolName(final String schoolName) {
this.schoolName = schoolName;
return this.self();
}
public B schoolYear(final String schoolYear) {
this.schoolYear = schoolYear;
return this.self();
}
protected abstract B self();
public abstract C build();
public String toString() {
String var10000 = super.toString();
return "Student.StudentBuilder(super=" + var10000 + ", schoolName=" + this.schoolName + ", schoolYear=" + this.schoolYear + ")";
}
}
private static final class StudentBuilderImpl extends StudentBuilder<Student, StudentBuilderImpl> {
private StudentBuilderImpl() {
}
protected StudentBuilderImpl self() {
return this;
}
public Student build() {
return new Student(this);
}
}
}
위 소스를 확인해보니, 상속을 받은 Student 클래스는 기존 Person 클래스와 별 다를 것이 없어 보입니다. 그러나, Generic을 사용하여 표기를 통한 부분으로 처음 오류 나는 부분을 해결한 것으로 생각됩니다.
추가적으로 궁금한 점이 있으시면 댓글로 남겨주세요.!
반응형