점점 강해지고 있습니다.
[Java] Record
들어가기 전에
Java에서 레코드(Record)란 보일러플레이트 코드를 최소화하기 위해 만들어졌다.
보일러플레이트 코드(Boilerplate Code) :
최소한의 변경으로 여러곳에서 재사용되며, 반복적으로 비슷한 형태를 띄는 코드를 말한다.
예를 들어 이름
, 나이
, 주소
를 담고 있는 클래스가 있다고 하자. 여기서 데이터를 뽑아내려면 일반적으로 getter와 setter를 작성하여 객체 간의 불변 데이터를 전달하도록 설계한다.
class PersonInfoClass {
String name;
int age;
String address;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
getter와 setter를 사용하기 위해서는 위처럼 메서드를 설계해야 하는데 데이터를 담기위한 클래스가 여러개라면? 반복적인 getXXX(), setXXX() 가 여러 개 만들어지며 코드가 길어질 것이다. 이를 보일러플레이트 코드라고 한다.
이를 최소화하기위해 Lombok 같은 라이브러리에서는 @
라는 어노테이션을 사용해 자동으로 만들어주는 기능을 제공하기도 한다.
import lombok.*;
@Getter
@Setter
class PersonInfoClass {
String name;
int age;
String address;
}
하지만 이런 코드는 라이브러리를 무조건 포함해야 한다는, Java의 한계로 작용하게 된다. 이를 해결하고자 Java14에서 preview로 Record를 선보이고, Java16에서 정식 기능으로 채택되었다.
Record의 선언법 및 특성
record PersonInfoRecord (
String name,
int age,
String address // 세미콜론(;)이 아닌 쉼표(,)로 데이터 구분
) {
static String str = "ABCD";
public int getBirthYear() {
return 2023 - age + 1;
}
} // 중괋호 안은 static 변수나 메서드를 작성하는 곳
- record 클래스는 final 클래스이라 상속할 수 없다.
- 각 필드는 private final 필드로 정의되어 생성 이후에는 불변 객체가 되어 값을 변경할 수 없다.
Record의 사용법
record PersonInfoRecord (
String name,
int age,
String address
) {
static String str = "ABCDEFG";
public int getBirthYear() {
return 2023 - age + 1;
}
}
public class RecordExample {
public static void main(String[] args) {
PersonInfoRecord pir = new PersonInfoRecord("전승준", 27, "대전");
System.out.println("이름: " + pir.name());
System.out.println("인사: " + pir.sayHello);
System.out.println("생년월일: "+pir.getBirthYear());
System.out.println(pir.toString());
}
}
출력
이름: 전승준
인사: Hello
생년월일: 1997
PersonInfoRecord[name=전승준, age=27, address=대전]
보일러플레이트 코드를 최소화하기 위해 만들어진 데이터 클래스이기 때문에 사용법은 일반 클래스와 같다.
record를 생성할 때는 아래와 같은 내용을 포함한다.
- 필드명을 딴 getter (getName()가 아닌 name())
- 모든 필드를 초기화하는 public 생성자
- 모든 필드가 일치할 때 동일한 클래스의 개체에 대해 true를 반환하는 equals 메서드
- 모든 필드가 일치할 때 동일한 값을 반환하는 hashCode 메서드
- 클래스 이름과 각 필드 이름 및 해당 값을 포함하는 toString 메서드
효율성
기존 class 사용 시 :
class PersonInfoClass {
String name;
int age;
String address;
public PersonInfoClass(String name, int age, String address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getAddress() {
return address;
}
@Override
public String toString() {
return "PersonInfoClass [name=" + name + ", age=" + age + ", address=" + address + "]";
}
@Override
public int hashCode() {
return Objects.hash(address, age, name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PersonInfoClass other = (PersonInfoClass) obj;
return Objects.equals(address, other.address) && age == other.age && Objects.equals(name, other.name);
}
}
record 사용 시 :
record PersonInfoRecord (
String name,
int age,
String address
) {}
정리
보일러플레이트 코드를 최소화하기 위해 만들어진 data class이다.
Reference
https://www.baeldung.com/java-record-keyword
https://coding-start.tistory.com/355