트랙
/
Java
Java
/
학습 과정
/
`switch`문
`s

`switch`문 에서 Java

2개의 연습 문제

`switch`문 소개

if/else 문과 마찬가지로, switch문을 사용하면 조건에 따라 코드를 실행해 프로그램의 흐름을 바꿀 수 있어요. 차이점은 switch문은 원시 타입이나 문자열 표현식의 값을 미리 정의된 상수 값과 비교만 할 수 있다는 점이에요.

switch문을 사용할 때 알아두면 유용한 키워드가 몇 가지 있어요.

  • switch: 이 키워드로 switch의 구조를 선언해요. 뒤에는 결과를 바꿀 표현식이나 변수가 와요.
  • case: 결과가 될 수 있는 여러 경우를 선언할 때 사용해요.
  • break: break 키워드는 원하는 흐름이 끝나는 지점에서 switch의 실행을 멈출 때 아주 유용해요. 이걸 빼먹으면 프로그램이 계속 실행되면서 예상치 못한 결과로 이어질 수 있어요.
  • default: 이름 그대로, 다른 어떤 case도 표현식의 결과와 일치하지 않을 때 기본 결과로 사용해요.

가장 단순한 형태로는 원시 타입이나 문자열 표현식을 검사하고, 그 값을 바탕으로 결정을 내려요. 예를 들어볼까요?

String direction = getDirection();
switch (direction) {
    case "left":
        goLeft();
        break;
    case "right":
        goRight();
        break;
    default:
        // otherwise
        markTime();
        break;
}

Java 14부터(그전에는 Java 12와 13에서 프리뷰로 사용할 수 있었어요) "향상된" switch 구현을 사용할 수 있어요.

  1. 하나의 case에 여러 값을 지정할 수 있어요. 전통적인 switch문에서는 폴스루를 사용할 수 있어요. 다음 예시에서 case 1과 case 3은 같은 동작을 실행해요. 이렇게 되는 건 case 1에서 break 키워드를 쓰지 않기 때문이에요.

    switch (number) {
        case 1:
        case 3:
            // do same stuff
            break;
        case 2:
            // do different stuff
            break;
        // (...)
    }
    

    향상된 switch expression에서는 case에 여러 값을 직접 지정할 수 있어요. 다음 예시를 봐요:

    switch (number) {
        case 1, 3:
            // do stuff
            break;
        case 2:
            // do other stuff
            break;
        // (...)
    }
    
  2. 이제 switch-statement나 switch expression을 작성할 수 있어요. 뭐가 다를까요? 기본적으로 문은 엄격한 로직을 요구하는 반면, 표현식은 값을 반환할 수 있어요. 다음과 같이 하는 대신:

    String result = "";
    switch (expression) {
        case "bob":
            result = "bob";
            break;
        // (...)
    }
    

    이렇게 할 수 있어요:

    String result = switch (expression) {
        case "bob":
            yield "bob";
        // (...)
    }
    

    yield는 switch 표현식에서 쓰인다는 점을 빼면 return처럼 동작해요. yield가 표현식을 끝내기 때문에 여기서는 break가 필요 없어요.

  3. _switch 문_과 _switch 표현식_의 또 다른 차이점은, _switch 표현식_에서는 모든 경우를 반드시 다뤄야 한다는 거예요. 가능한 모든 값에 대한 case를 두거나, default case를 사용하면 돼요.

  4. : 대신 ->를 사용할 수 있어요. ->를 쓰면 break 키워드를 넣지 않아도 돼요. 두 표기법을 모두 쓸 수 있지만, 하나의 switch 안에서는 한 가지만 사용해야 해요.

     switch(expression) {
         case 1 -> yield "one"
         case 2 -> yield "two"
         default: yield "other number" // Removing this will result in a compile error
     }
    
  5. 스코프. 전통적인 switch는 전체 switch에 스코프가 하나뿐이라서, 스코프 때문에 예상치 못한 동작이 생길 수 있어요.

     switch(expression) {
         case 1:
             String message = "something";
             break;
         case 2:
             String message = "anything";
             break;
         // (...)
     }
    

    이 예시는 switch 안에서 message가 두 번 선언되기 때문에 동작하지 않아요. 다음과 같이 하면 해결할 수 있어요:

     switch (expression) {
         case 1: {
             String message = "something";
             break;
         }
         case 2: {
             String message = "anything";
             break;
         }
         // (...)
     }
    

    {}가 case의 스코프를 구분해 주기 때문이에요. 하지만 {}는 필수가 아니라서 직관적이지 않아요. 그런데 새 -> 표기법을 사용하면, 뒤에 단일 문이나 표현식, throw 문, 또는 {} 블록 중 하나가 반드시 와야 해요. 이제 헷갈릴 일이 없어요!

향상된 switch에 대한 더 많은 정보는 이 글과 이 글, 그리고 공식 Oracle 문서에서 찾을 수 있어요.

또한 Java 21에는 Guarded Patterns라는 기능이 추가되어, case 레이블 자체에서 검사를 할 수 있어요.

String dayOfMonth = getDayOfMonth();
String day = "";
return switch (day) {
    case "Tuesday" when dayOfMonth == 13 -> "Forbidden day!!";
    case "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" -> "Week day";
    case "Saturday", "Sunday" -> "Weekend";
    default -> "Unknown";
};

Java 21의 switch 표현식에 대한 더 많은 정보는 이 블로그에서 찾을 수 있어요.

GitHub에서 편집 링크가 새 창이나 탭에서 열려요

`switch`문 배우기