버그는 switch 문의 첫 번째 case에 있습니다. case 끝에 break 문이 없죠. 즉 switch는 두 번째 case를 실행합니다. 첫 번째 case는 실패하고 항상 cruiseControl.grantAccess()를 실행하겠죠.

    switch 문은 이러한 동작으로 악명 높습니다. break 문 또는 블록 끝에 다다라야 실행을 멈추거든요. 어떤 C 스타일 언어든 이와 같은 switch 실행 시맨틱(semantic)을 사용합니다. 자바도 C 언어의 계보를 이어 받았습니다.

    switch가 이렇게 동작하는 것은 좀 더 간결하고 길이도 짧은 코드를 작성할 수 있기 때문입니다. switch를 쓰면 조건 표현식 몇 개를 평가하지 않아도 되거든요. 심지어 자바 7부터는 switch 문에서 정수, 문자, enum(열거형)뿐만 아니라 문자열도 쓸 수 있게 되었습니다.

    하지만 지난 수년 간 득보다 실이 많았고 break 문을 빠뜨려 야기된 버그도 매우 많았습니다. 간혹 의도적으로 break를 누락했다면 반드시 주석을 남기는 것이 좋습니다!

    버그가 없는 코드를 봅시다.

    class BoardComputer {
    
        CruiseControl cruiseControl;
    
        void authorize(User user) {
            Objects.requireNonNull(user);
            switch (user.getRank()) {
            case UNKNOWN:
                cruiseControl.logUnauthorizedAccessAttempt();
                break;
            case ASTRONAUT:
                cruiseControl.grantAccess(user);
                break;
            case COMMANDER:
                cruiseControl.grantAccess(user);
                cruiseControl.grantAdminAccess(user);
                break;
            }
        }
    }
    신간 소식 구독하기
    뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.