티스토리 뷰

[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을 사용하지 못한다. 이를 주의하여 사용하자.


참고

 

 

 

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함