ㅤㅤㅤ

문자열을 위한 switch 본문

プログラミング/JAVA

문자열을 위한 switch

ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ 2017. 6. 15. 09:33

Java7에서 개선된 언어기능: 문자열을 위한 switch 구문개선


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 문장의 구문은 다음과 같습니다. 
1SwitchStatement:
2    switch ( Expression )
3        SwitchBlock
Expression에는 char, byte, short, int, Character, Byte, Short, Integer, String 그리고 enum 타입이 올 수 있으며, 기존에 허용되지 않던 String 타입이 추가되었습니다. 

Java7 이전에는 switch 문장에서 String 타입 표현식을 허용하지 않았기 때문에 다중 if-else 문장으로 처리할 수 밖에 없었습니다. 
01public void withoutString(String str) {
02 
03    if(str.equals("bob") || str.equals("sam"))
04        //do something ...
05    else if(str.equals("carl") || str.equals("joy"))
06        //do something ...
07    else if(str.equals("anna") || str.equals("haron"))
08        //do something ...
09    else
10        //do something ...
11 
12}
위 코드를 switch 문장으로 옮기면 다음과 같습니다. 
01public void withString(String str) {
02     
03    switch(str) {
04        case "bob"case "sam":
05          //do something ...
06          break;
07        case "carl"case "joy":
08          //do something ...
09          break;
10        case "anna"case "haron":
11          //do something ...
12          break;
13        default:
14          //do something ...
15    }
16 
17}
두 코드를 비교해 보면 if-else 문장의 경우 매번 String 클래스의 equals() 메서드로 문자열을 비교해야하는 번거로움이 있음을 알 수 있습니다.

개인적으로는 개선된 기능을 통해 코드의 가독성이 좋아졌다고 생각되나 주의해야 할 점이 있습니다.
  • 표현식에 사용되는 String 객체가 null인지 확인해야 함
  • String 비교시 대소문자 구분("Sam"과 "sam"은 다른 객체)
  • 오직 String 타입의 참조변수만 허용

첫 번째 주의할 사항은 바로 표현식에 사용되는 str이 null인 경우입니다. if-else 문장에서 문자열을 비교하는 equals() 메서드 호출도 null.equals()는 NullPointerException에 해당합니다. 이러한 경우 null 문자열와의 비교는 항상 false를 반환하도록 다음과 같은 트릭을 사용하여 NullPointerException을 방지할 수 있습니다. 
1if("bob".equals(str) || ...

Java7의 switch 문장의 경우, 다음 코드와 같이 case문에서 null 상수를  사용할 수 없기때문에 적절한 전처리가 필요합니다. 
01switch(str) {
02 
03    case null//ERROR!!
04        .....
05        break;
06 
07    case "bob"case "sam":
08        System.out.println("bob or sam");
09        break;
10 
11    default:
12       System.out.println("default");
13       break;
14}

두 번째 사항은 문자열 객체의 대소문자 구분에 관한 내용이고, 마지막으로 오직 String 타입만 Expression에서 허용되므로 다음과 같은 코드는 컴파일에러입니다. 
01public void switchTest() {
02 
03    //OK: "bob" is-a Object!!
04    Object str = "bob";
05 
06    //ERROR!!
07    switch(str) {
08        ...
09    }
10}

참고로 switch 문장에서 String 타입이 지원되기까지 대략16년 정도 걸렸다고 합니다. 1995년에 보고된 다음 Bug 리포트를 참조해 보시기 바랍니다. 


Comments