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

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

         

        jdk pattern matching

        • jdk 14  버전에서 instanceof 연산자에 대한 pattern matching 기능이 JEP 305 를 통해 preview 기능으로 처음 제안됨
        • jdk 16 버전에서 instanceof 연산자에 대한 pattern matching 기능이 JEP 394 를 통해 정식 기능으로 릴리즈됨
        • jdk 17 버전에서 switch 표현식과 구문에 대한 pattern matching 기능이 JEP 406 을 통해 preview 기능으로 제안됨

         

        pattern matching for instanceof

        타입 패턴 형태로 타입 이름과 결과를 바인딩할 변수로 구성됩니다. instanceof 연산자에 타입 패턴을 적용하면 타입 체크와 형변환이 간소화됩니다.

        아래와 같은 instanceof 에 대한 기존 코드가 있습니다.

        if (obj instanceof String) {
        	String s = (String) obj;
            ....
        }

        위 코드에는 테스트(obj 가 String 타입인지?), 변환(obj 를 String 으로 형변환), 새로운 지역 변수 선언의 세 가지 작업을 수행합니다. 이미 obj 가 String 타입인지 테스트를 했음에도 명시적으로 형변환을 수행하는 것은 불필요 한 작업이 될 수 있습니다. 가장 중요한 것은 타입에 대한  테스트, 형변환, 지역변수 할당과 같은 반복으로 인해서 눈에 띄지 않는 오류를 발생 시킬 수 있다는 것입니다.

        instanceof 에 대한 pattern matching 을 적용한 코드는 아래와 같습니다.

        if (obj instanceof String s) {
        	//obj 를 String 타입 변수 s 에 할당한 s 를 사용
        }

        pattern matching 을 사용하게 되면 명시적인 형변환과 지역변수 정의 및 할당을 제거하여 코드를 간소화 시킬 수 있습니다.

         

        scope of pattern variables

        public interface Shape {}
        public class Rectangle implements Shape {}
        public class Circle implements Shape {}
        public class Triangle implements Shape {}
        ...
        
        if (shape instanceof Rectangle r) {
        	//Rectangle 타입의 패턴 변수 r 을 이 영역에서만 사용가능 합니다.
        } else if (shape instanceof Circle c) {
        	//Circle 타입의 패턴 변수 c 는 이 영역에서만 사용가능 합니다.
        	//Rectangle 타입의 패턴 변수 r 은 이 영역에서는 사용할 수 없습니다.
        } else {
        	//이 영역에서는 패턴 변수 r, c 모두 사용할 수 없습니다.
        }

        패턴 변수를 정의한 구문 밖으로 패턴 변수는 확장 될 수 있습니다.

        public interface Shape {
        	void print();
        }
        
        public class Rectangle implements Shape {}
        public class Circle implements Shape {}
        public class Triangle implements Shape {}
        
        ...
        
        void scopeTest(Shape shape) {
        	//if 블록 영역 밖이 Rectangle r 패턴 변수를 사용할 수 있는 영역입니다.
        	if (!(shape instanceof Rectangle r)) {
        		//Rectangle 타입의 패턴 변수 r 은 이 블록에서는 사용할 수 없습니다.
        		Sytem.out.println("rectangle 이 아닙니다.");
        		//하지만 아래 return 문이 없다면 if 블럭 밖에서 패턴 변수 r 을 사용할 수 없습니다.
        		//즉 패턴 변수 r 을 사용할 수 있는 영역과 아닌 영역이 명확하게 구분 되어야 합니다.
        		return;
        	}
            
        	//이 영역에서 패턴 변수 r 을 사용할 수 있습니다.
        	r.print();
        }
        
        =======================================================================
        
        void scopeTest(Shape shape) {
        	if (!(shape instanceof Rectangle r)) {
        		//패턴 변수 r 을 사용할 수 없는 영역이기 때문에
        		//cannot find symbol (variable r) 오류 발생!!!
        		r.print();
        	}
        }
        
        =======================================================================
        
        void scopeTest(Shape shape) {
        	if (!(shape instanceof Rectangle r)) {
        		Sytem.out.println("rectangle 이 아닙니다.");
        	}
        
        	//패턴 변수 r 을 사용할 수 없는 영역안에 return 문이 없기 때문에
        	//cannot find symbol (variable r) 오류 발생!!!
        	r.print();
        }

        if 문 안의 표현식에서 패턴 변수를 사용할 수 있습니다. 각 Rectangle, Triangle, Circle 클래스에 Boolean 타입을 리턴하는 isXXXX() 메소드가 있다고 가정합니다.

        void scopeTest(Shape shape) {
        	//패턴 변수 r을 if문 내에서 사용할 수 있습니다.
            if (shape instanceof Rectangle r && r.isShape()) {
                r.print();
            }
            //패턴 변수 t를 if문 내에서 사용할 수 있습니다.
            else if (shape instanceof Triangle t && t.isShape()) {
                t.print();
            }
            //패턴 변수 c를 if문 내에서 사용할 수 있습니다.
            else if (shape instanceof Circle c && c.isShape()) {
                c.print();
            } else {
                throw new IllegalArgumentException();
            }
        }
        
        
        void scopeTest2(Shape shape) {
            // ||(or) 연사자를 통해서 shape 는 Rectangle 타입이 아닌 경우에도
            // r.isShape() 이 호출되기 때문에 컴파일러 오류가 발생합니다. !!!
            // cannot find symbol (variable r)
            // symbol: variable r
            if (shape instanceof Rectangle r || r.isShape()) {
                ...
            }
        }
        반응형
        저작자표시 비영리 변경금지 (새창열림)

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

        Java - 람다 표현식 (lambda expression) 개요  (0) 2023.09.10
        jdk pattern matching for switch  (0) 2023.08.26
        java switch expression - from jdk 14  (0) 2023.08.20
        java Array vs ArrayList  (0) 2023.08.19
        java record 용법 - from jdk 14  (0) 2023.08.19
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바