파란하늘의 지식창고
Published 2019. 7. 18. 14:48
JDK 12 New Features Study/Java
반응형

JDK의 버전별 변경 사항은 이곳을 참고하세요.

Spec

Java SE 12 Platform JSR (386)에 정의된 바와 같이 JSR 386 구현이 목표

실제 Spec은 Final Release Specification 문서를 참고해야 함

Final Release Specification Feature summary

전체 JEP Feature 목록은 OpenJDK의 JDK 12 문서로 확인할 수 있다.

Component Feature  
core-libs / java.lang.invoke JVM Constants API  
specification / language Switch Expressions (Preview)  

Switch Expressions (Preview)

해당 기능은 preview 기능이기 때문에 실행 시 --enable-preview 옵션을 추가해야 동작한다.

명령문이나 표현식으로 사용할 수 있도록 switch 문을 확장하고 두 양식 모두 "기존" 또는 "단순화된" 범위 지정 및 제어 흐름 행동을 사용할 수 있게 된다.

이 변경 사항은 pattern matching (JEP 305)을 사용할 수 있는 방법을 준비한다.

이전 switch 구문의 경우 불필요하게 장황하고 누락된 break 문으로 우발적인 오류가 발생하기 쉬웠다.

switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        System.out.println(6);
        break;
    case TUESDAY:
        System.out.println(7);
        break;
    case THURSDAY:
    case SATURDAY:
        System.out.println(8);
        break;
    case WEDNESDAY:
        System.out.println(9);
        break;
}

이제 "case L ->" 형태로 오른쪽의 코드만 실행된다는 것을 지정할 수 있게 되어 다음처럼 사용할 수 있게 된다.

switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}

"case L ->" 구문의 오른쪽 부분은 표현식, 블록 또는 throw 호출을 할 수 있다.

switch 내의 로컬 변수의 범위가 switch 블록이었던 기존의 불편한 방식이 해결된다.

switch (day) {
    case MONDAY:
    case TUESDAY:
        int temp = ...
        break;
    case WEDNESDAY:
    case THURSDAY:
        int temp2 = ...     // Why can't I call this temp?
        break;
    default:
        int temp3 = ...     // Why can't I call this temp?
}

위처럼 switch 블록 내 로컬 변수를 외부에서 쓸 수 없어서 아래처럼 사용했었다.

int numLetters;
switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        numLetters = 6;
        break;
    case TUESDAY:
        numLetters = 7;
        break;
    case THURSDAY:
    case SATURDAY:
        numLetters = 8;
        break;
    case WEDNESDAY:
        numLetters = 9;
        break;
    default:
        throw new IllegalStateException("Wat: " + day);
}

이제 다음처럼 사용할 수 있다.

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};

"case L ->" 오른쪽이 단일 표현식으로 처리되지 않는 경우 블록 구문과 break 반환 값 설정을 사용하면 된다.

int j = switch (day) {
    case MONDAY  -> 0;
    case TUESDAY -> 1;
    default      -> {
        int k = day.toString().length();
        int result = f(k);
        break result;
    }
};

위의 경우 case에 해당하지 않으면 default에서 블록 내 여러 줄의 처리를 수행한 후 break에서 result를 반환하고 있다.

하지만 이로 인해 각 case에서 반환할 값을 break로 지정하지 않은 경우 어떻게 처리해야 하는가와 같은 새로운 문제가 발생하게 된다.

int i = switch (day) {
    case MONDAY -> {
        System.out.println("Monday"); 
        // ERROR! Block doesn't contain a break with value
    }
    default -> 1;
};
i = switch (day) {
    case MONDAY, TUESDAY, WEDNESDAY: 
        break 0;
    default: 
        System.out.println("Second half of the week");
        // ERROR! Group doesn't contain a break with value
};

for문과 같이 사용하는 경우 switch 구문 내에서 continue 가 switch의 구문 실행을 뛰어넘을 수 없게 된다.

for (int i = 0; i < MAX_VALUE; ++i) {
        int k = switch (e) { 
            case 0:  
                break 1;
            case 1:
                break 2;
            default: 
                continue z; 
                // ERROR! Illegal jump through a switch expression 
        };
    ...
}

 

반응형
profile

파란하늘의 지식창고

@Bluesky_

도움이 되었다면 광고를 클릭해주세요