Java7에 추가된 Java 언어의 7가지 개선사항 중 본 포스트에서는
"Strings in 'switch' statements"에 대해 정리하고, 몇 가지 주의사항에 대해 언급하겠습니다. 7가지 개선사항은 다음과 같습니다.(
OpenJDK: "Project Coin",
JSR-334)
- Binary Literals
- Underscores in Numeric Literals
- Strings in switch Statements
- The try-with-resources Statement
- Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
- Type Inference for Generic Instance Creation
- Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods
Java7의 Language Specification에 기술된 switch 문장의 구문은 다음과 같습니다.
Expression에는
char, byte, short, int, Character, Byte, Short, Integer, String 그리고 enum 타입이 올 수 있으며, 기존에 허용되지 않던
String 타입이 추가되었습니다.
Java7 이전에는 switch 문장에서 String 타입 표현식을 허용하지 않았기 때문에
다중 if-else 문장으로 처리할 수 밖에 없었습니다.
01 | public void withoutString(String str) { |
03 | if (str.equals( "bob" ) || str.equals( "sam" )) |
05 | else if (str.equals( "carl" ) || str.equals( "joy" )) |
07 | else if (str.equals( "anna" ) || str.equals( "haron" )) |
위 코드를 switch 문장으로 옮기면 다음과 같습니다.
01 | public void withString(String str) { |
04 | case "bob" : case "sam" : |
07 | case "carl" : case "joy" : |
10 | case "anna" : case "haron" : |
두 코드를 비교해 보면 if-else 문장의 경우 매번 String 클래스의 equals() 메서드로 문자열을 비교해야하는 번거로움이 있음을 알 수 있습니다.
개인적으로는 개선된 기능을 통해 코드의 가독성이 좋아졌다고 생각되나 주의해야 할 점이 있습니다.
- 표현식에 사용되는 String 객체가 null인지 확인해야 함
- String 비교시 대소문자 구분("Sam"과 "sam"은 다른 객체)
- 오직 String 타입의 참조변수만 허용
첫 번째 주의할 사항은 바로 표현식에 사용되는 str이 null인 경우입니다. if-else 문장에서 문자열을 비교하는 equals() 메서드 호출도 null.equals()는 NullPointerException에 해당합니다. 이러한 경우 null 문자열와의 비교는 항상 false를 반환하도록 다음과 같은 트릭을 사용하여 NullPointerException을 방지할 수 있습니다.
1 | if ( "bob" .equals(str) || ... |
Java7의 switch 문장의 경우, 다음 코드와 같이 case문에서 null 상수를 사용할 수 없기때문에 적절한 전처리가 필요합니다.
07 | case "bob" : case "sam" : |
08 | System.out.println( "bob or sam" ); |
12 | System.out.println( "default" ); |
두 번째 사항은 문자열 객체의 대소문자 구분에 관한 내용이고, 마지막으로 오직 String 타입만 Expression에서 허용되므로 다음과 같은 코드는 컴파일에러입니다.
01 | public void switchTest() { |
참고로 switch 문장에서 String 타입이 지원되기까지 대략16년 정도 걸렸다고 합니다. 1995년에 보고된 다음
Bug 리포트를 참조해 보시기 바랍니다.