목차
Java는 Java 14에서 레코드 타입(Record Type)을 도입했습니다. Java 21 버전에서는 레코드 클래스의 인스턴스를 분해하고 더 정교한 데이터 쿼리를 가능하게 하는 레코드 패턴(Record Patterns)이 도입되었습니다.
레코드 타입이란 무엇인가?
Java는 Java 14에서 레코드라는 특별한 타입을 도입했습니다.
레코드는 제한된 형태의 클래스 타입으로, 주로 데이터를 저장하는 목적으로 사용됩니다. 레코드는 클래스보다 간결합니다.
레코드 타입 정의의 예시입니다:
// 레코드 타입 정의
record Point(int x, int y)
위 코드는 아래와 같은 기능을 수행합니다:
Point
라는 레코드 타입을 선언합니다.- 변수
x
와y
에 대한 private final 필드를 포함합니다. x()
와y()
라는 메소드 이름으로 int 타입의 접근자 메소드를 포함합니다.x
와y
멤버를 가진 public 생성자를 제공합니다.equals()
,hashCode()
,toString()
메소드의 구현을 포함합니다.
Java 21에서 도입된 레코드 패턴
이 글에서는 Java 21에서 도입된 레코드 패턴에 대해 논의할 것입니다. 레코드 패턴은 JEP 405와 함께 Java 19에서 미리보기 기능으로 처음 도입되었으며, JEP 432를 통해 Java 20에서 추가로 개선되었습니다. Java 21은 JEP 440을 통해 이 기능에 몇 가지 주요 변화를 가져왔습니다.
레코드 패턴의 주요 목적은 패턴 매칭을 확장하여 레코드 인스턴스를 분해하는 것입니다. 이를 통해 레코드 인스턴스에 대한 더 간결하고 정교한 데이터 쿼리를 작성할 수 있습니다. 레코드 패턴은 또한 중첩 패턴을 지원하여 더 구성 가능한 데이터 쿼리를 형성할 수 있습니다.
Java 16의 instanceof 연산자 개선
Java 16에서는 패턴 매칭을 허용하는 타입 패턴을 instanceof
연산자에 도입했습니다:
// Java 16 이전
public void sayHello(Object message) {
if (message instanceof String) {
String messageStr = (String) message;
System.out.println(messageStr);
}
}
// Java 21 이후
public void sayHello(Object message) {
if (message instanceof String messageStr) {
System.out.println(messageStr);
}
}
위 코드에서, message
가 String
타입인 경우 instanceof
평가가 참이 되고, messageStr
변수는 message
의 값으로 초기화됩니다. 이는 Java 16 코드에서 추가 캐스팅이 필요했던 것을 없앴습니다.
레코드와 레코드 패턴
레코드는 데이터를 저장하는 데 사용됩니다. 주된 목적은 POJO 클래스의 장황함을 줄이는 것입니다. 레코드는 레코드 변수에 대한 접근자 메소드를 제공하여 쉽게 접근할 수 있게 합니다. Java 21은 분해(de-structuring)를 통해 레코드 변수를 접근하는 방법을 단순화합니다.
예시를 통해 설명해보겠습니다 :
record Point(int x, int y) {}
// Java 16 사용
void print(Object object) {
if (object instanceof Point p) {
int x = p.x();
int y = p.y();
System.out.printf("X is %d, y is %d%n", x, y);
}
}
// Java 21 사용
void print(Object object) {
if (object instanceof Point(int x, int y)) {
System.out.printf("X is %d, y is %d%n", x, y);
}
}
Java 16을 사용할 때는 레코드 접근자 메소드를 사용하여 변수를 얻어야 했습니다. 그러나 Java 21에서는 패턴 매칭이 객체를 Point
타입으로 내부적으로 캐스팅할 뿐만 아니라, 변수를 분해하여 사용할 수 있게 합니다. 위의 예시는 간단한 레코드 분해를 보여줍니다.
또, 우리는 중첩된 레코드 패턴으로 이 분해를 확장할 수 있습니다.
예시를 통해 이를 살펴보겠습니다 :
// 레코드 타입 Point 정의
record Point(int x, int y) {}
// enum 타입 Color 정의
enum Color { RED, GREEN, BLUE }
// ColoredPoint 정의
record ColoredPoint(Point p, Color c) {}
// 특정 x-y 평면상의 점을 정의하는 RandomPoint
record RandomPoint(ColoredPoint cp) {}
이제 RandomPoint
인스턴스를 정의하고 점의 멤버 변수를 접근해봅시다 :
// 레코드 인스턴스화
Point p = new Point(1, 2);
ColoredPoint coloredPoint = new ColoredPoint(p, Color.RED);
RandomPoint randomPoint = new RandomPoint(coloredPoint);
// 중첩된 레코드 패턴을 사용하여 Point 변수 접근
void nestedPrint(Object object) {
if (object instanceof RandomPoint(ColoredPoint(Point(int x, int y), Color c))) {
System.out.printf("X is %d, y is %d, Color is %s%n", x, y, c.name());
}
}
// nestedPrint(randomPoint)
// 출력: X is 1, y is 2, Color is RED
위 코드에서 중첩된 분해가 if
구문 안에서 어떻게 이루어지는지 주목하세요.
이 글에서는 Java 21의 레코드 패턴 사용법을 탐구했습니다.
먼저 레코드 타입에 대해 논의한 후 레코드 패턴을 소개했습니다. 마지막으로 예제를 통해 중첩된 레코드 패턴을 탐구해 보았습니다.
읽어주셔서 감사합니다! 😊
개발 관련 궁금증이나 고민이 있으신가요?
아래 링크를 통해 저에게 바로 문의해 주세요! 쉽고 빠르게 도움 드리겠습니다.
'Development > Code' 카테고리의 다른 글
Spring Boot: 스프링 부트 공통 라이브러리 구축하기 (공통 모듈) (4) | 2024.07.02 |
---|---|
Spring Boot: 사용 가능한 메모리보다 더 많은 데이터 쿼리하기 (0) | 2024.07.01 |
자바 개발자를 위한: 개발 시간을 단축시킬 6가지 Lombok 기능 (0) | 2024.06.29 |
자바 개발자를 위한: 생산성을 향상시킬 10가지 Guava 기능 (0) | 2024.06.28 |
알아두면 좋은 Spring Boot 기능 10가지 (0) | 2024.06.28 |