record
는 특수한 클래스로, 일반 클래스보다 덜 복잡한 방식으로 일반 데이터를 모델링할 수 있는 친구다.
kotlin의 data class와 비슷하다고 생각하면 된다.
기존에 우리가 데이터를 만들기 위해서는 다음과 같이 구현해야 했다.
public final class Rectangle {
private final double length;
private final double width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
double length() { return this.length; }
double width() { return this.width; }
// Implementation of equals() and hashCode(), which specify
// that two record objects are equal if they
// are of the same type and contain equal field values.
public boolean equals...
public int hashCode...
// An implementation of toString() that returns a string
// representation of all the record class's fields,
// including their names.
public String toString() {...}
}
생성자에 getter 메소드를 전부 다 구현해줘야 했다.
으!
그치만 record
의 등장부터는 이렇게 하지 않아도 된다는 사실.
record Rectangle(double length, double width) { }
record
는 이와 같이 header에 content에 대한 설명을 담는다.
→ 자동으로 적절한 접근자, 생성자, equals, hashCode, toString 메소드가 생성됨
→ 모든 record의 필드는 final
이다! 레코드는 정말 간단하게 “데이터 캐리어”의 역할만 하기 때문.
❗내부적으로 조금만 더 더 자세히 알아보자면..
record
는 이런 것들을 자동으로 선언한다.
private final
)Rectangle::length()
같은..)record Rectangle(double length, double width) {
public Rectangle(double length, double width) {
if (length <= 0 || width <= 0) {
throw new java.lang.IllegalArgumentException(
String.format("Invalid dimensions: %f, %f", length, width));
}
this.length = length;
this.width = width;
}
}
기존에 위와 같이 주절주절 써줘야 했던 걸 암묵적인 간결한 생성자를 선언할 수 있음! 아래처 컴팩트한 생성자를 선언하면서 유효성 검사도 할 수 있다. (주의 : record
에서만 사용 가능!!)record Rectangle(double length, double width) {
public Rectangle {
if (length <= 0 || width <= 0) {
throw new java.lang.IllegalArgumentException(
String.format("Invalid dimensions: %f, %f", length, width));
}
}
}
⭕
record Rectangle(double length, double width) {
static double goldenRatio;
static {
goldenRatio = (1 + Math.sqrt(5)) / 2;
}
public static Rectangle createGoldenRectangle(double width) {
return new Rectangle(width, width * goldenRatio);
}
}
Rectangle r = new Rectangle(4,5);
final
이기 대문에 명시적 확장은 불가함.record Triangle<C extends Coordinate> (C top, C left, C right) { }
record Customer(...) implements Billable { }
record Rectangle(
@GreaterThanZero double length,
@GreaterThanZero double width) { }
❌
record Rectangle(double length, double width) {
BiFunction<Double, Double, Double> diagonal;
{
diagonal = (x, y) -> Math.sqrt(x*x + y*y);
}
}
record Shape(
String name
) { }
class Rectangle extends Shape{
// 불가!
}
⚠️ 중첩된 record
도 가능합니다.
record Rectangle(double length, double width) {
// Nested record class
record RotationAngle(double angle) {
public RotationAngle {
angle = Math.toRadians(angle);
}
}
// Public instance method
public Rectangle getRotatedRectangleBoundingBox(double angle) {
RotationAngle ra = new RotationAngle(angle);
double x = Math.abs(length * Math.cos(ra.angle())) +
Math.abs(width * Math.sin(ra.angle()));
double y = Math.abs(length * Math.sin(ra.angle())) +
Math.abs(width * Math.cos(ra.angle()));
return new Rectangle(x, y);
}
}
record
를 사용하면 짧아집니다.⇒ 반복적인 데이터 클래스를 record
로 대체하자!
kotlin을 활용한 안드로이드 개발을 하면서 동시에 Java로 서버 공부를 하고 있는 입장에서..
record를 보자마자 ‘어? data class랑 똑같네?’ 라는 생각이 들었다.
// Kotlin
data class FriendCardModel(
val friendId: Int,
val friendName: String,
val imageUrl: String,
val state: BbangZipCardState,
@DrawableRes val imgSrc: Int = 0,
)
// Java
record Rectangle(double length, double width) { }
코틀린
val(불변)
, var(가변)
모두 사용 가능자바
final
→ Setter 존재 X, 불변성 어느정도 보장⇒ 코틀린에 비해 자바의 record
는 좀 더 불변성에 제약을 강제해둔 안정적인 Class
이거 영문이랑 구글 자동번역 번갈아가면서 읽으면 이해가 쏙쏙 됩니다..