Record는 Java14 부터 도입되고 16부터 class처럼 타입으로 사용이 가능해졌습니다.
final로 구성되기에 VO로 많이 사용되는 방식입니다.
정의 방법
불변 데이터 객체로 Person을 정의하면 아래와 같이 정의 해야합니다.
public class Person {
private final String name;
private final String address;
public Person(String name, String address) {
this.name = name;
this.address = address;
}
@Override
public int hashCode() {
return Objects.hash(name, address);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (!(obj instanceof Person)) {
return false;
} else {
Person other = (Person) obj;
return Objects.equals(name, other.name)
&& Objects.equals(address, other.address);
}
}
@Override
public String toString() {
return "Person [name=" + name + ", address=" + address + "]";
}
// standard getters
}
하지만 같은 프로세스를 반복해야한다는 점!
IDE에서는 많은 클래스를 자동으로 생성할 수 있지만, 새 필드를 추가할 때 클래스를 자동으로 업데이트 하지는 못합니다.
즉, toString을 만들더라도 하나의 파라미터가 변경되면 모든 값을 수정해줄 필요가 있습니다!!
레코드를 사용하면 필드 유형과 이름만 필요한 불변 데이터 클래스입니다.
또한 equals, hashcode, tostring과 private, final field, public constructor는 Java 컴파일러에 의해 생성됩니다.
따라서 위의 코드를 아래와 같이 만들면 됩니다.
public record Person(String name, String address) {}
사용 사례 Test
그럼 Test 해보겠습니다.
String name = "Scott";
String address = "Busan";
Person p1 = new Person(name, address);
Person p2 = new Person(name, address);
System.out.println(p1.name.equals(p2.name));
System.out.println(p2.address.equals(p2.address));
System.out.println("p1 HashCode : " + p1.hashCode());
System.out.println("p2 HashCode : " + p2.hashCode());
System.out.println("p1 data : " + p1.toString()+ "p2 data : " + p2.toString());
값이 같은지, hashcode는 어떻게 나오는지, ToString은 되는지 확인해보면
현재 내부 값이 같아서 HashCode값이 같게 나오고, 내부 값이 다르면 다른 HashCode 값이 나옵니다.
그리고 이 모든 동작이 정상적으로 동작하는 것을 볼수 있습니다.
Record class에는 Static value, 정적메서드도 들어 갈 수 있습니다.
{} 안에 값을 주입하면됩니다.
public record Person(String name, String address) {
public static String UNKNOWN_ADDRESS = "Unknown";
public static Person unnamed(String address) {
return new Person("Unnamed", address);
}
}
Record의 사용방법에 대해 배웠으니 이번에는 제약사항에 대해 배워보겠습니다.
Record 제약사항
record는 다른 클래스를 상속받을 수 없으며, private final fields 이외의 인스턴스 필드를 선언할 수 없습니다.
(다만, static field는 넣어줄수 있습니다.)
암시적으로 final이며 abstract가 되지 못합니다. 따라서 다른 클래스나 레코드에 의해 변경될 수 없음을 의미합니다.
다만, record는 최상위 레벨로 선언되거나, 중첩될 수 있으며, 제너릭, 인터페이스 구현 등 일반 클래스처럼 동작합니다.
또한 record body에는 static 메서드, static 필드, static 이니셜라이저, 생성자, 인스턴스 메서드 및 중첩 타입을 선언할 수 있습니다.
만약 getName이 실제 팀 rule이라면?
이때는 p1.name()이 아니라 p1.getName()으로 찾아야 겠죠? 컨벤션을 지키려면 ..!@!
이때는 아래와 같이 구현하면 getName()으로 검색을 할수 있게 됩니다.
public record Person(@Getter String name, String address) {}
'기술 스텍 > Java' 카테고리의 다른 글
[Java] 컴포지션이란? (60) | 2024.04.12 |
---|---|
[Java] Interned String (1) | 2024.04.05 |
[Java] 프로세스 vs 스레드? (0) | 2024.02.21 |
자바 버전에 따른 차이 (0) | 2024.02.19 |
Casting 이란? (0) | 2024.02.17 |