[JAVA]
[Java] switch 표현식
handr95
2023. 3. 21. 21:51
반응형
전형적인 switch 표현식
@NoArgsConstructor
@AllArgsConstructor
public class Player {
private int id;
private PlayerTypes type;
public static Player createPlayer(PlayerTypes type){
switch (type) {
case TENNIS :
return new TennisPlayer();
case FOOTBALL :
return new FootballPlayer();
case UNKNOWN :
return new UnknownPlayerException("Player type is unknown");
// default문을 빠뜨리면 컴파일 에러가 발생됨
default:
throw new IllegalArgumentException("invalid type : " + type);
}
}
}
default가 빠진 문제 있는 표현식
@NoArgsConstructor
@AllArgsConstructor
public class Player {
private int id;
private PlayerTypes type;
public static Player createPlayer(PlayerTypes type){
Player player = null;
switch (type) {
case TENNIS :
Player player = new TennisPlayer();
case FOOTBALL :
Player player = new FootballPlayer();
case UNKNOWN :
return new UnknownPlayerException("Player type is unknown");
// default가 빠져있더라도 컴파일 오류를 내지 않음
}
return player;
}
}
이때는 defualt를 빠뜨려도 컴파일 에러가 발생되지 않는다. 누락된 default문으로 player에 null이 그대로 반환 될수 있다.
개선된 switch 표현식 - JDK 12
public static Player createPlayer(PlayerTypes type){
return switch (type) {
case TENNIS -> new TennisPlayer();
case FOOTBALL -> new FootballPlayer();
case UNKNOWN -> throw new UnknownPlayerException("invalid type : " + type);
// default는 생략 가능
default -> throw new IllegalArgumentException("invalid type : " + type);
};
}
JDK12 switch는 enum 값을 전부 다뤘는지 감지할 수 있고 defulat가 불필요하면 강요하지 않는다. 가령 default를 제거하고 PlayerTypes enum에 새 항목을 추가하면 컴파일러는 에러 메시지를 출력한다.

아래와 같이 람다 스타일의 문법이 아닌 콜론(:)과 break문도 사용 가능 하다
public static Player createPlayer(PlayerTypes type){
return switch (type) {
case TENNIS :
break new TennisPlayer();
case FOOTBALL :
break new FootballPlayer();
case UNKNOWN :
throw new UnknownPlayerException("Player type is unknown");
};
}
jdk13부터는 break문이 yield로 대체되어 아래와 같이 사용해야 합니다.
public static Player createPlayer(PlayerTypes type){
return switch (type) {
case TENNIS :
yield new TennisPlayer();
case FOOTBALL :
yield new FootballPlayer();
case UNKNOWN :
throw new UnknownPlayerException("Player type is unknown");
};
}
다수의 case 레이블 - JDK 12
jdk 12 이전의 switch 문은 case당 하나의 레이블을 허용했지만, jdk 12부터는 case에 콤마로 구분된 다수의 레이블을 둘 수 있다.
public static Player createPlayer(PlayerTypes type){
return switch (type) {
case TENNIS, FOOTBALL, SNOOKER
-> new Team();
case UNKNOWN
-> new Unknown();
};
}
명령문 블록 - JDK 12
public static Player createPlayer(PlayerTypes type){
return switch (type) {
// 명령문을 중괄호로 묶어 처리
case TENNIS, FOOTBALL, SNOOKER -> {
System.out.println("create new team");
break new Team();
}
case UNKNOWN -> {
System.out.println("create new unknown");
break new Unknown();
}
};
}
jdk 13이후 버전은 아래처럼 사용해줘야합니다.
public static Player createPlayer(PlayerTypes type){
return switch (type) {
// 명령문을 중괄호로 묶어 처리
case TENNIS, FOOTBALL, SNOOKER -> {
System.out.println("create new team");
yield new Team();
}
case UNKNOWN -> {
System.out.println("create new unknown");
yield new Unknown();
}
};
}
이때 return이 아닌 break/yield로 중괄호 블록을 빠져나왔다. switch 문에서는 return문을 사용할수는 있지만 중괄호 구문에서는 return을 사용하지 못한다. 이를 주의하여 사용하자.
참고
- http://www.yes24.com/Product/Goods/113416654
- https://mkyong.com/java/java-12-switch-expressions
- https://mkyong.com/java/java-13-switch-expressions
반응형