Java

[Java 16] Switch Expression, instanceof Pattern Matching

Switch Expression

 

AS-IS

  • 기존 Switch 문법의 경우 Statement(문) 형식
    • Statement: 변수에 할당 불가능. 하나의 값으로 표현 불가능
  • 각 case를 case 값: 형태로 사용(colon case label)
  • 각 분기가 끝날 때마다 break;를 붙여야함
  • 여러 분기를 한번에 처리하고 싶다면 colon case label을 연이어 적어야함
public String calcGrade(int score) {
        String grade = ""; // 변수 할당 불가능. 먼저 선언
        switch (score) {
            case 5: // colon case label
                grade = "A";
                break; // break 생략 시 이후 로직도 진행
            case 4:
            case 3: // 여러 case의 경우 colon case label 연이어 사용
                grade = "B";
                break;
            case 2:
                grade = "C";
                break;
            default:
                grade = "F";
        }
        return grade;
}

 

TO-BE

  • Switch 문법을 Expression(표현식)으로 처리 가능
    • 결과값이 정해지는 문장. 변수에 할당 가능.
  • break 생략하고 즉시 yield 값 형태로 처리 가능
  • 여러 분기를 한번에 처리하고 싶다면 case 4, 3: 형태로 comma 붙여 처리 가능
  • case 5 -> 값 형태를 통해 yield 생략 가능 (arrow case label)
    • 중괄호를 통한 여러 줄 처리 가능
    • 중괄호 시에는 return에 대해 yield 키워드 필요
  • enum과 함께 사용 시 enum의 모든 값에 대한 case 작성한다면 default 생략 가능
    • enum은 컴파일 타임에 타입을 모두 알 수 있음
  • Expression으로 사용 가능 / 문법 간소화를 통해 if-else 문을 대체하는 분기 처리로 활용하기 용이해짐
public String calcGrade(int score) {
        return switch(score) { // Expression이므로 바로 return 가능
            case 5 -> "A"; // arrow case label
            case 4,3 -> "B";
            case 2 -> { // 중괄호 처리 가능
                System.out.println("C");
                yield "C";
            }
            default -> "F";
        };
}
    
enum Color {RED, YELLOW, GREEN}

public String getColor(Color color) {
        return switch(color) {
            case RED -> "빨강";
            case YELLOW -> "노랑";
            case GREEN -> "초록";
            // 모든 타입이 case에 포함되므로 default 생략 가능
        };
}

 

 

 

 

instanceof Pattern Matching

  • instanceof : 변수가 특정 타입의 인스턴스인지 확인
public static class Animal { }

public static class Dog extends Animal { }

public static class Cat extends Animal { }

public static boolean checkCat(Animal animal) {
    return animal instanceof Cat;
}

public static void main(String[] args) {
    Dog dog = new Dog();
    Cat cat = new Cat();
    System.out.println(checkCat(dog)); // false
    System.out.println(checkCat(cat)); // true
}

 

 

AS-IS

  • instanceof로 하위 타입을 체크했더라도 해당 하위 타입의 메서드에 접근하기 위해서는 형변환 필수
public static String checkCat(Animal animal) {
  if (animal instanceof Dog) { // 인스턴스 타입 체크를 했더라도
     return ((Dog) animal).bow(); // 형변환 필수
  } else if (animal instanceof Cat) {
     return ((Cat) animal).yao();
  }
  return "누구인가";
}

 

TO-BE

  • instanceof로 하위 타입 체크 시 해당 하위 타입으로 형변환된 값 할당되어 사용 가능
  • 해당 하위타입임이 확실시 되는 모든 범위에서 하위 타입으로 형변환된 값을 사용 가능 
  • 하위타입 체크 이후 해당 하위타입의 메서드 등에 접근해야 하는 경우 짧은 코드로 처리가 유용
public static String howl(Animal animal) {
    if (animal instanceof Dog dog) { // instanceof를 통해 형변환 즉시 가능
        return dog.bow(); // 하위타입 메서드 접근 가능
    } else if (animal instanceof Cat cat){
        return cat.yao();
    }
    return "누구인가";
}

public static String imDog(Animal animal) {
    if (!(animal instanceof Dog dog)) { // 이후 animal은 Dog 타입임이 확실
        return "나는 애옹";
    }
    return dog.bow(); // if문 밖에서도 Dog 메서드 접근 가능
}

 

 

 


Reference

인프런 - 자바 9부터 자바 21까지