• 티스토리 홈
  • 프로필사진
    알쓸개잡
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
알쓸개잡
  • 프로필사진
    알쓸개잡
    • 분류 전체보기 (93)
      • 스프링부트 (52)
      • AWS (5)
      • 쿠버네티스 (7)
      • 자바 (19)
      • 인프라 (1)
      • ETC (8)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      • 반응형
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • java 21 - Record Patterns 소개
        2024년 03월 20일
        • 알쓸개잡
        • 작성자
        • 2024.03.20.:43
        반응형

        Java의 pattern matching 도입 이후 구문 단순화와 코드 가독성 및 안전성 향상을 목표로 점진적으로 발전해 왔다.

        switch 표현식에서의 pattern matching, instanceof에 대한 pattern matching이 대표적이다.

        이번 포스팅에서는 이전 버전의 preview 기능을 거쳐 java 21에서 정식 릴리즈된 Record Patterns에 대해서 소개하고자 한다.

        이전에 다뤘던 pattern matching에 대해서는 아래 포스팅에 정리해 보았다.

        2023.08.26 - [자바] - jdk pattern matching for switch

         

        jdk pattern matching for switch

        jdk 17 이전 릴리즈 에서는 switch 문의 선택자 표현식은 숫자, 문자열, Enum 상수로만 평가되었고 case 레이블은 상수만 지원을 하였습니다. jdk 17 릴리즈 부터는 switch 문의 선택자 표현식은 모든 타입

        devel-repository.tistory.com

        2023.08.26 - [자바] - jdk pattern matching for instanceof

         

        jdk pattern matching for instanceof

        pattern matching 은 객체가 특정 구조를 가지고 있는지 테스트한 다음 일치하는 경우 해당 객체에서 데이터를 추출하는 작업을 포함합니다. 이번 포스팅에서는 instanceof 연사자에 pattern matching 을 적

        devel-repository.tistory.com

        더불어 Record 클래스 타입에 대한 소개는 아래 포스팅에 정리해 보았다.

        2023.08.19 - [자바] - java record 용법 - from jdk 14

         

        java record 용법 - from jdk 14

        jdk 14 에서 새로운 타입 으로 record 가 preview 형태로 도입되었습니다. Enum 타입과 마찬가지로 record 타입은 몇가지 제약사항을 가지고 있으며 불변의 데이터 셋을 정의하는데 상당한 간소함을 제공

        devel-repository.tistory.com

         

        Record 패턴은 Record 클래스 유형의 인스턴스인지 테스트하고 (레코드 클래스 참조), 인스턴스인 경우 구성 요소 값에 대해서 재귀적으로 패턴 일치를 수행할 수 있게 한다.

        참고로 Record 패턴의 도입 배경은  JEP440 에서 확인해 볼 수 있다.

         

        일반 용법

        아래 샘플 코드는 인자로 전달된 obj 인스턴스가 Point 레코드의 인스턴지 여부를  Record 패턴과 함께 테스트한다.

        record Point(double x, double y) {
            static void checkPattern(Object obj) {
                if ( obj instanceof Point(double x, double y) ) {
                    System.out.println("x: " + x + ", y: " + y);
                }
            }
        }
        
        =====================================
        
        Point point = new Point( 1.0, 2.0 );
        Point.checkPattern( point );
        
        ======================================
        
        출력
        Point x: 1.0, y: 2.0

        샘플코드에서 알 수 있듯이 Record 패턴을 통해서 if문 내부에서 obj 인스턴스에서 x, y 값을 직접 추출하여 Point레코드의 접근자 메서드를 자동으로 호출하게 된다.

         

        Record 패턴은 타입과 Record 패턴 목록으로 구성된다. 위 예시 코드에서 타입은 Point이고 패턴 목록은 (double x, double y)다.

        체크하는 인스턴스가 null인 경우 어떠한 레코드 패턴과도 일치하지 않는다.

         

        다음과 같이 Record 패턴 대신에 타입 패턴을 사용할 수 있다.

        static void checkType(Object obj) {
            if ( obj instanceof Point p ) {
                System.out.println("Point x: " + p.x + ", y: " + p.y);
            }
        }

        타입 패턴을 사용하는 경우에는 Record 패턴과 달리 x, y를 직접 호출하여 access 해야 한다.

         

         

        Generic Records

        Record 클래스가 Generic인 경우 Record 패턴에서 타입 인수를 명시적으로 지정할 수 있다.

        record ValueRecord<T>(T t) {
            static void checkTypeAndPrintValue(ValueRecord<String> obj) {
                if ( obj instanceof ValueRecord<String>(String s) ) {
                    System.out.println("String ValueRecord: " + s);
                }
            }
        }
        
        ===========================================
        
        ValueRecord<String> valueRecord = new ValueRecord<>( "generic record" );
        ValueRecord.checkTypeAndPrintValue( valueRecord );
        
        ===========================================
        
        출력
        String ValueRecord: generic record

        checkTypeAndPrintValue 메서드의 파라미터에 Generic 타입이 명시적으로 지정되지 않은 경우에는 type cast 관련 오류를 만날 수 있다.

        static void notCheckTypeAndPrintValue(ValueRecord obj) {
            // error : ValueRecord cannot be safely cast to ValueRecord<String>
            if ( obj instanceof ValueRecord<String> v ) {
                System.out.println("ValueRecord: " + v.t);
            }
        }
        
        static void notCheckTypeAndPrintValue(ValueRecord obj) {
            // no error
            if ( obj instanceof ValueRecord<?> v ) {
                System.out.println("ValueRecord: " + v.t);
            }
        }

         

         

        타입 추론

        Record 패턴의 구성 요소 목록에서 var를 사용할 수 있다.

        static void checkPattern(Object obj) {
            if ( obj instanceof Point(var x, var y) ) {
                System.out.println("Point x: " + x + ", y: " + y);
            }
            else {
                System.out.println("not Point record type");
            }
        }

        위 코드에서 컴파일러는 변수 x, y는 double로 타입 추론을 한다.

        컴파일러는 패턴을 허용하는 모든 구조체(switch 문, switch 표현식, instanceof 표현식)에서 레코드 패턴의 타입을 추론할 수 있다.

         

         

        Nested Record Patterns

        중첩된 Record 패턴을 사용할 수 있다.

        record NestedRecord(Point p1, Point p2) {
            static void checkPattern(Object obj) {
                if ( obj instanceof NestedRecord(Point(var x, double y), var p2) ) {
                    System.out.println("Point1 x: " + x + ", y: " + y);
                    System.out.println("Point2 x: " + p2.x + ", y: " + p2.y);
                }
                else {
                    System.out.println("not Point record type");
                }
            }
        }
        
        ========================================
        
        Point p1 = new Point( 1.0, 2.0 );
        Point p2 = new Point( 3.0, 4.0 );
        NestedRecord nestedRecord = new NestedRecord( p1, p2 );
        NestedRecord.checkPattern( nestedRecord );
        
        ========================================
        
        출력
        Point1 x: 1.0, y: 2.0
        Point2 x: 3.0, y: 4.0

         

        Record 패턴은 기존 패턴 일치 기능에 원활하게 통합되어 레코드 해체를 단순화할 뿐 아니라 코드 가독성과 유지 관리성을 향상한다.

         

        끝.

        반응형
        저작자표시 비영리 변경금지 (새창열림)

        '자바' 카테고리의 다른 글

        Java Concurrent Map: 스레드 안전성을 보장하는 Atomic 메서드 소개  (0) 2024.06.10
        java - 디렉토리 삭제 + 특정 조건의 파일 삭제하기  (0) 2024.03.31
        apache tika 라이브러리를 이용하여 일반 문서 및 암호화된 문서의 정보 알아보기  (0) 2024.03.08
        java21 - scoped value에 대해서 알아보자  (0) 2023.11.26
        java 21 처리량 향상을 위한 대안 - virtual thread 알아보자  (0) 2023.11.24
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바