불변 객체
불변 객체는 생성된 후 그 상태를 변경할 수 없는 객체를 의미한다.
프로젝트를 진행하다 보면 데이터베이스 결과, 쿼리 결과 등 단순히 담기 위한 객체를 생성하는 경우가 있다.
불변 객체를 사용함으로써 내부 필드값의 불변성을 보장해서 유지보수에서 이점을 챙길 수 있기 때문이다.
Java에서 불변 객체
java에서 불변 객체를 만들려면 아래와 같은 과정이 필요하다.
- private final로 선언을 해주어야 한다.
- 해당 객체를 만들기 위한 생성자도 만들어야 한다.
- 객체의 동등성을 위해 equals와 hashCode를 구현해야 한다.
- 필드에 접근하기 위한 getter를 정의해야 한다.
- 디버깅을 위한 toString를 정의해야 한다.
public class User {
private final String name;
private final String email;
public User(String name, String email) {
this.name = name;
this.email = email;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
@Override
public boolean equals(Object o) {
if (this == o) return true; // 동일한 객체를 가리키는 경우 true
if (o == null || getClass() != o.getClass()) return false; // null이거나 클래스가 다른 경우 false
User user = (User) o;
if (!name.equals(user.name)) return false; // name 필드 비교
return email.equals(user.email); // email 필드 비교
}
@Override
public int hashCode() {
int result = name.hashCode(); // name의 해시 코드 사용
result = 31 * result + email.hashCode(); // email의 해시 코드를 추가적으로 사용
return result;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", email='" + email + '\'' +
'}';
}
}
단순히 name, email을 갖는 불변 객체를 만든 건데 너무 많은 메서드를 정의해 주어야 한다.
또 만약 필드값을 추가할 때 많은 코드들이 수정되어야 한다.
그래서 Record를 사용을 한다.
Record
record를 사용하면 위와 동일한 코드를 단순히 아래와 같이 정의해 위에서 정의한 불변객체와 동일한 기능을 수행할 수 있다.
public record User(String name, String email) {
}
Record 사용법
- 선언 동시에 내부에서 사용할 필드값들을 정의 해야한다.
- 내부에서 추가하면 에러가 발생 한다.
- 하지만 (static 정적 필드)와 (메서드)는 추가할 수 있다.
- 다른 클래스를 상속받을 수 없다.
- new 키워드를 사용해서 생성할 수 있다.
User user = new User("이름", "email@naver.com");
- 내부 필드에 접근은 get이 아닌 필드 이름을 사용해서 호출이 가능하다.
String name = user.name();
String email = user.email();
- 만약 자동으로 생성된 toString, equlas 같은 함수를 재정의 하고 싶으면 override로 재정의 할 수 있다.
public record User(String name, String email){
@Override
public String toString() {
return "이름: " + this.name";
}
}
- 컴팩트 생성자를 사용할 수 있다.
컴팩트 생성자
- 생성자에 사용하는 파라미터와 레코드의 필드값이 같으면 생략이 가능하다.
- this.name = name;같은 할당 부분은 생략이 가능하다. (마지막에 추가된다.)
public record User(String name, String email){
public User{
validate(name, email);
}
}
Summary
레코드는 불변 데이터를 전달하기 위한 캐리어다.
개발자가 확장 가능한 동작보다는 불변의 데이터 모델링에 집중할 수 있도록 도와준다.
'자바' 카테고리의 다른 글
For vs Stream (0) | 2024.06.23 |
---|---|
[자바] Reflection (0) | 2024.05.23 |