우테코 페어 매칭 미션이 시작됐다.
하늘에 맹세코 두 달 동안 단 한 줄의 코드도 작성하지 않고 놀기만 했더니 진짜 아무것도 기억이 안난다. 그러니 이번 주는 겸손한 마음으로 자바 재활 운동 느낌으로 모르는 것을 마구 배워가자 싶었다.
이번 미션 페어는 '코기'이다. 고기를 좋아해서 코기라고 한다. 옆에서 코기가 코딩하는 걸 지켜보면서 자바에 대해 몰랐던 기능을 많이 배울 수 있었다 (고마워요). 오늘은 그 중에서 record 타입에 대해 정리해보려고 한다.
자바 16부터 정식으로 지원되기 시작한 신기능이다. 주로 DTO 표현에 사용된다.
일단 사용형태를 알아보자.
public final class Member {
private final String account,
private final String name;
private final int age;
public Member(String account, String name, int age) {
this.account = account;
this.name = name;
this.age = age;
}
public Long getAccount() {
return account;
}
...
@Override
public String toString() {
return "User{" + "account = " account + ...
}
}
public record Member(
String account,
String name,
int age
) {
...
}
위와 같이 클래스 명 뒤에 소괄호로 파라미터를 지정하듯 클래스의 필드들을 정의한다.
이때 필트의 접근 지정자는 입력할 수 없다.
별 내용이 없더라도 {} 는 생략할 수 없다.
Record 클래스의 프로퍼티를 가져다 쓸 때는 일반적인 getXXX 방식이 아니라 필드의 이름 그대로 XXX()를 사용한다. (위의 예시에서 name을 가져올 때 member.name()으로 가져올 수 있음)
모든 필드가 묵시적으로 final로 선언된다. 따라서 Setter도 존재하지 않고 상태값 변경 시도 시 에러가 발생하는 등 객체의 불변성이 어느정도 보장된다.
모든 것이 final인 Record 특성 상 copy()는 굳이 지원하지 않는다.
필드에 객체가 있다면 불변성이 보장되지 않을 수도 있다
- 모든 객체는 참조 주소를 전달하는 call by reference로 동작하기 때문에 객체를 단순 조회한 후 상태값을 바꾸면 원본 객체의 상태값이 바뀌게 된다. 따라서 불변 객체로 만들어야 해당 record 클래스의 불변성을 보장한다.
Rcord 클래스는 이미 java.lang에 있는 추상 클래스인 Record를 상속받아 구현되었기 때문에 더이상 상속할 수도 받을 수도 없다.
정의된 필드를 기반으로 equals(), hashCode() 메서드를 자동으로 생성해준다. 덕분에 데이터 비교를 위해 위 함수들을 따로 오버라이딩 해 주지 않아도 되고, 필드의 추가/제거에 유연하다.