JDK 12 에서 preview 기능으로 새롭게 추가된 switch expression(표현식)이 jdk 14 에서 정식 릴리즈 되었습니다.
이번 포스팅에서는 정식 릴리즈된 switch expression 에 대해서 소개와 사용 방법에 대해서 소개합니다.
JDK14 에 정식 릴리즈된 switch expression 은 JEP 361 에서 제안되었습니다.
기존의 switch 구문(statement) 뿐 아니라 하나의 표현식(expression) 으로써 switch 를 제공합니다.
"case L ->" Labels
switch label 이 일치하는 경우 label 오른쪽에 있는 코드만 실행되도록 하는 새로운 형태의 스위치 lable 입니다. "case L ->" 로 표현합니다. 아래 코드는 기존의 switch 구문(statement)을 나타냅니다.
public enum City { SEOUL, NEWYORK, LONDON }
// ...
String countryName;
City city = City.SEOUL;
switch (city) {
case SEOUL:
countryName = "Korea";
break;
case NEWYORK:
countryName = "America";
break;
case LONDON:
countryName = "England";
break;
default:
countryName = "unknown";
}
System.out.println(countryName);
도시의 나라 이름을 countryName 변수에 할당하여 출력하는 기존의 switch 구문입니다. 기존의 switch 구문을 사용하는 대신에 countryName 을 리턴하는 switch expression(표현식) 을 사용하면 코드를 더욱 간결하고 효율적으로 개선할 수 있습니다.
아래는 "case L ->" switch expression 을 사용한 코드입니다.
public enum City { SEOUL, NEWYORK, LONDON }
...
City city = City.SEOUL;
String countryName =
switch (city) {
case SEOUL -> "Korea";
case NEWYORK -> "America";
case LONDON -> "England";
default -> "unknown";
};
System.out.println(countryName);
기존의 코드와 비교해서 더욱 간결하면서도 break 문이 제거됨으로써 break 문의 누락 실수를 방지할 수도 있습니다. 위 switch 문은 statement 가 아닌 expression 임을 알아야 합니다. 그렇게 때문에 값을 리턴할 수도 있습니다.
"case L ->" Labels 와 yield
switch expression 에서 yield 는 값을 리턴하는 키워드 입니다.
"case L ->" 문법에서 여러 문장을 사용하는 경우에는 해당 코드를 블록으로 묶고 yield 를 통해 리턴할 수 있습니다.
public enum City { SEOUL, NEWYORK, LONDON }
...
City city = City.SEOUL;
String countryName =
switch (city) {
case SEOUL -> {
System.out.println("Korea");
yield "Korea";
}
case NEWYORK -> {
System.out.println("America");
yield "America";
}
case LONDON -> {
System.out.println("England");
yield "England";
}
default -> {
System.out.println("unknown");
yield "unknown";
}
};
"case L:" Labels 와 yield
"case L ->" 이 아닌 "case L:" 문법에서도 yield 키워드를 사용하여 값을 리턴할 수 있습니다.
public enum City { SEOUL, NEWYORK, LONDON }
...
City city = City.SEOUL;
String countryName =
switch (city) {
case SEOUL: yield "Korea";
case NEWYORK: yield "America";
case LONDON: yield "England";
default: yield "unknown";
};
System.out.println(countryName);
yield 문을 사용하면 switch statement(구문) 와 switch expression(표현식) 을 쉽게 구분할 수 있습니다. switch expression 이 아닌 switch statement 는 break 문의 대상이 될 수 있습니다. 반대로 switch expression 은 반환 문의 대상이 될 수 있습니다.
오라클 공식문서에서는 "case L:" 를 사용하는 것보다 "case L ->" expression 을 사용하는 것을 권장합니다. "case L:" 문법을 사용하는 경우 break 혹은 yield 문을 누락하는 실수가 발생할 소지가 있기 때문입니다.
Exhaustiveness (완전성)
switch문(statement)과 달리 switch표현식(expression) 은 가능한 모든 값에 대해 일치하는 switch label 이 있어야 합니다. 따라서 switch expression 에는 default 문이 필요합니다. 단 enum 타입과 같이 알려진 상수를 포함하는 switch expression 의 경우 default 문이 없을 때는 컴파일러에서 암묵적으로 default 문을 넣습니다.
또한 값을 할당하는 switch expression 이 사용되는 경우에 switch expression 은 반드시 값을 리턴해야 합니다.
String countryName =
switch (city) {
//java: incompatible types: bad type in switch expression
//void cannot be converted to java.lang.String
//컴파일 error 발생!!
case SEOUL -> System.out.println("Korea");
default -> "unknown";
};
===========
switch (city) {
//java: not a statement
//리턴된 값을 할당하는 부분이 없기 때문에 컴파일 error 발생!!
case SEOUL -> "Korea";
default -> "unknown";
};
===========
switch (city) {
//ok
case SEOUL -> System.out.println("Korea");
default -> System.out.println("unknown");
};
switch expression에서 단일값(리턴값이 있는) 으로 평가되는 경우에는 break, continue 문을 사용하여 switch expression 을 건널 뛸 수 없습니다. 이 경우에는 예외로 처리를 해야 합니다.
public enum City { SEOUL, NEWYORK, LONDON }
...
for (City city : City.values()) {
String countryName = switch (city) {
case SEOUL -> "Korea";
case LONDON -> "England";
//java: illegal start of expression compile error!!!
default -> continue;
};
System.out.println(countryName);
}
위 코드와 같이 loop 구문 안에서 사용되는 switch expression 은 continue 대신에 예외로 처리를 해야 합니다.
public enum City { SEOUL, NEWYORK, LONDON }
...
for (City city : City.values()) {
try {
String countryName =
switch (city) {
case SEOUL -> "Korea";
case LONDON -> "England";
default -> throw new RuntimeException("not processed, " + city);
};
System.out.println(countryName);
} catch (RuntimeException e) {
System.out.println(e.getMessage());
}
}
=====================================
실행결과
Korea
not processed, NEWYORK
England
JDK 14 에 정식 릴리즈된 switch expression 에 대한 오라클 공식 문서 링크 남깁니다.
이 글을 읽으시는 분에게 도움이 되었기를 바랍니다.
'자바' 카테고리의 다른 글
jdk pattern matching for switch (0) | 2023.08.26 |
---|---|
jdk pattern matching for instanceof (0) | 2023.08.26 |
java Array vs ArrayList (0) | 2023.08.19 |
java record 용법 - from jdk 14 (0) | 2023.08.19 |
CompletableFuture 를 알아보자 (0) | 2023.08.06 |
댓글