• 티스토리 홈
  • 프로필사진
    알쓸개잡
  • 태그
  • 블로그 관리
  • 글 작성
알쓸개잡
  • 프로필사진
    알쓸개잡
    • 분류 전체보기 (98)
      • 스프링부트 (57)
      • AWS (5)
      • 쿠버네티스 (7)
      • 자바 (19)
      • 인프라 (1)
      • ETC (9)
  • 리얼포스 Realforce R3S 키보드 R3SD13 토프레 무점접키보드, 기본, 기본, 텐키리스
    반응형
# 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일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
목차
표시할 목차가 없습니다.
    • 안녕하세요
    • 감사해요
    • 잘있어요

    티스토리툴바