2025. 2. 28. 18:43ㆍTIL
✔오늘 배운 중요한 🔑 point
- lombok 라이브러리는 보일러플레이트 코드를 자동으로 생성해주는 도구
- @Data는 불변 객체를 만들때 안전하게 사용하기 위한 기능 모음집
🎯 오늘 배운 내용
@AllargusConstructor
class에 있는 모든 필드에 대한 생성자를 자동으로 생성
import lombok.AllArgsConstructor;
@AllArgsConstructor
public class Member {
private String name;
private int age;
}
해당 생성자를 자동으로 생성해준다.
public Member(String name, int age) {
this.name = name;
this.age = age;
}
AccessLevel의 default값이 PUBLIC이므로 기본적으로 생성되는 생성자의 접근타입은 PUBLIC
사용 가능한 AccessLevel 값들 : (PROTECTED, PUBLIC, PACKAGE-PRIVATE, PRIVATE)
@RequiredArgsConstructor
final 필드와 @NonNull로 명시된 필드만을 포함하는 생성자를 자동으로 생성
import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public class Member {
private final String name;
private int age;
private final String address;
@NonNull
private String foo;
}
final 필드에 대한 생성자를 생성하며 @NonNull로 명시된 필드인 foo에 대해서 생성자를 생성해준다.
public Member(String name, String address, String foo) {
if (foo == null) {
throw new NullPointerException("foo is marked non-null but is null");
}
this.name = name;
this.address = address;
this.foo = foo;
}
마찬가지로 AccessLevel의 default값은 PUBLIC
@noArgsConstructor
매개변수가 없는 기본생성자를 자동으로 생성
import lombok.NoArgsConstructor;
@NoArgsConstructor
public class Member {
private String name;
private int age;
}
name은 null로, age는 0의 값이 된다. @NonNull키워드가 있더라도 기본 생성자에서는 null체크를 하지않는다.
public Person() {
}
@Getter
모든 필드의 getter 메소드를 자동으로 생성
import lombok.Getter;
@Getter
public class Member {
private String name;
private int age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Getter를 class에 선언하면 해당 class의 모든 필드에 대한 getter 메소드가 자동으로 생성되며
필드에 개별적으로 적용하게 되면 해당 필드에 대한 getter 메소드만 자동으로 생성된다. (setter도 마찬가지)
import lombok.Getter;
import lombok.Setter;
public class Member {
@Getter @Setter
private String name; // name 필드에 대해 getter와 setter 메서드 생성
@Getter
private int age; // age 필드에 대해서는 getter만 생성
@Setter
private String address; // address 필드에 대해서는 setter만 생성
}
참고자료: https://projectlombok.org/features/GetterSetter
@Getter and @Setter
projectlombok.org
@ToString
class의 필드 값을 출력해주는 toString() 메소드를 자동으로 생성
import lombok.ToString;
@ToString
public class Member {
private String name;
private int age;
}
기본적으로 모든 필드의 값들을 출력해준다.
public String toString() {
return "Member(name=" + name + ", age=" + age + ")";
}
만약 password같은 민감한 정보를 포함시키고싶지 않거나 id같이 필수로 포함시켜야하는 경우에는 Include와 Exclude를 사용하면 된다.
import lombok.ToString;
@ToString(exclude = {"password"}, onlyExplicitlyIncluded = true)
public class User {
@ToString.Include
private String username;
private String password;
private String email;
private String foo;
}
해당 코드에서 exclude={"password"} 로 인하여 password는 toString 메소드에 포함되지 않으며 onlyExplicitlyIncluded = true로 인하여 @ToString.Include로 명시된 필드만 toString()에 포함되도록 한다.
public String toString() {
return "User(username=" + username + ")";
}
공식문서를 보니 Exclude또한 필드에서 명시하는식으로 편하게 사용할수 있다.
참고 자료:https://projectlombok.org/features/ToString
@ToString
projectlombok.org
@Setter
class 필드의 setter 메소드를 자동으로 생성
import lombok.Setter;
@Setter
public class Member {
private String name;
private int age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@EqualsAndHashCode
equals() , hashCode() 메소드를 자동으로 생성
import lombok.EqualsAndHashCode;
@EqualsAndHashCode
public class Member {
private String name;
private int age;
}
동등성 비교를 하는 equals 메소드와 해시값을 계산하는 hashCode 메소드를 생성한다.
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Member member = (Member) o;
return age == member.age && Objects.equals(name, member.name);
}
public int hashCode() {
return Objects.hash(name, age);
}
@Equals, @HashCode 가 따로따로 존재하지 않는 이유는 JAVA에서 Equals와 HashCode가 서로 관련이 깊은 Contract 관계이기 때문이다.
해당 문서를 보면 모든 Java class는 암묵적으로 equals 함수와 hashCode 함수를 가진다고 나와있으며
동일한 객체는 반드시 동일한 hashCode를 가져야 하며
동일하지 않은 두 객체가 같은 hashCode를 가질수도 있다 라는 규칙이 정해져있는것을 확인할 수 있다.
즉 객체가 동일하다면 hashCode는 반드시 동일하며
반대로 hashCode가 동일하다고 해서 객체가 반드시 동일하다고는 볼 수 없다.
참고자료: https://www.baeldung.com/java-equals-hashcode-contracts
@Data
@ToString, @EqualsAndHashCode, @Getter(모든 필드), @Setter(final 필드 제외), @RequiredArgsConstructor 의 모음집
위에 서술한 많은 기능들을 한꺼번에 사용하는 어노테이션
객체를 작성할때 반복적으로 사용해야하는 메소드들을 자동으로 생성하는 딸깍(?) 어노테이션
import lombok.Data;
@Data
public class Member {
private String name;
private int age;
}
final필드와 @NonNull이 명시된 필드로 구성된 생성자를 생성하며 getter 메소드, setter 메소드(final 필드 제외), toString 메소드, equals, hashCode 메소드를 자동으로 생성해주게 된다.
@noArgsConstructor가 포함되지 않는 이유는 @Data는 final필드에 대해서 Setter 메소드를 생성하지 않고 기본 생성자는 final 필드 초기화를 보장할수 없기 때문에 자동으로 생성되지 않는다.
🤔 어떻게 활용할까?
package hjp.shoppingmall.domain.member.entity;
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "member")
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@ToString
public class MemberEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "loginId")
private String loginId;
@Column(name = "password")
@ToString.Exclude
private String password;
@Column(name = "nickname")
private String nickname;
@Column(name = "ROLE")
private String memberRole;
@Column(name = "created_at", updatable = false)
private LocalDateTime createTime;
@PrePersist
public void prePersist() {
this.createTime = LocalDateTime.now();
}
public MemberEntity(String loginId, String password, String nickname, String memberRole) {
this.loginId = loginId;
this.password = password;
this.nickname = nickname;
this.memberRole = memberRole;
}
}
해당 코드를 오늘 배운 내용을 이용하여 수정할수 있을것 같다.
수정 후
import jakarta.persistence.*;
import lombok.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "member")
@Data
@NoArgsConstructor
public class MemberEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "loginId")
private String loginId;
@Column(name = "password")
@ToString.Exclude
private String password;
@Column(name = "nickname")
private String nickname;
@Column(name = "ROLE")
private String memberRole;
@Column(name = "created_at", updatable = false)
private LocalDateTime createTime;
@PrePersist
public void prePersist() {
this.createTime = LocalDateTime.now();
}
public MemberEntity(String loginId, String password, String nickname, String memberRole) {
this.loginId = loginId;
this.password = password;
this.nickname = nickname;
this.memberRole = memberRole;
}
}
Jpa를 이용하기 위해서는 기본생성자가 필수이기 때문에 @noargsConstructor를 사용하였고, @Getter와 @Setter, @ToString, @AllArgsConstructor 등의 어노테이션을 @Data 하나로 사용하는것으로 코드가 좀 더 간결해졌다.
lombok 라이브러리에서 제공하는 기능들을 어떤 상황에서 써야할지에 대해서 공부가 조금은 된것 같아 마구잡이로 어노테이션을 사용하는 일이 조금 줄어들것 같다.

📓 오늘의 한줄
"In the midst of winter, I found there was, within me, an invincible summer."
- Albert Camus -
'TIL' 카테고리의 다른 글
Stripe API (0) | 2025.03.24 |
---|---|
JWT Claims instance is immutable and may not be modified. 오류 해결 (1) | 2025.02.27 |
JAVA로 개발하는 쇼핑몰 프로젝트 (JAVA VS KOTLIN) (0) | 2025.02.26 |
HTTP/3 VS HTTP/2 (0) | 2025.02.25 |
OPEN AI를 이용한 TIL 추천 서비스 NEXTIL (0) | 2025.02.24 |