programing

String switch 문이 늘 케이스를 지원하지 않는 이유는 무엇입니까?

nicescript 2023. 1. 13. 20:07
반응형

String switch 문이 늘 케이스를 지원하지 않는 이유는 무엇입니까?

이 왜 '7'인지이에요.switch되지 않습니다.nullNullPointerException다음 코멘트 행을 참조해 주세요(의 Java 튜토리얼에서 인용한 예:

{
    String month = null;
    switch (month) {
        case "january":
            monthNumber = 1;
            break;
        case "february":
            monthNumber = 2;
            break;
        case "march":
            monthNumber = 3;
            break;
        //case null:
        default: 
            monthNumber = 0;
            break;
    }

    return monthNumber;
}

하면 될 입니다.ifswitch

damryfbfnetsi가 코멘트에서 지적했듯이 JLS §14.11에는 다음과 같은 주의사항이 있다.

「 」의 null스위치 라벨로 인해 실행할 수 없는 코드를 쓸 수 없게 됩니다. 경우,switch즉 표현식입니다.String합니다.null실행 시.Java 프로그래밍 언어 설계자의 판단에 따르면, 이는 전체 문장을 묵묵히 건너뛰거나 라벨 뒤에 있는 문장을 실행하도록 선택하는 것보다 더 나은 결과입니다(있는 경우).

(내 것을 제외)

은 사용 ,case null:언어 디자이너의 의도를 파악할 수 있도록 합리적으로 보입니다.

구현 세부사항을 살펴보면 Christian Hujer의 블로그 게시물에는 그 이유에 대한 통찰력 있는 추측이 있습니다.null할 수 에서는 할 수 없습니다).enumString★★★★★★★★★★★★★★★★★★:

★★★★★★★★★★★★★★★★★★★★.switch문은 일반적으로 탭리스위치 바이트 코드로 컴파일됩니다. ' 인수는 '물리적인' 인수는 인'switch int됩니다. 스위치를 켤 int 값은 메서드를 호출하여 결정됩니다.Enum.ordinal() [...] 합니다. [...] 0으로 하다

맵핑, 맵핑, 맵핑, 맵핑.null로로 합니다.0 값의 늘과 되지 않습니다.enum enum null null null null null num 。 1.1에서것 같은데는 바꿀.단, 그렇게 정의되어 있지 않으며, 이 정의는 변경할 수 없습니다.

한편, 「 」는, 「 」, 「 」의 사이에String스위치는 다른 방법으로 구현됩니다.enum가 첫 했습니다.레퍼런스가 「 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」, 「」의 경우입니다.null.

으로는 ★★★★★★★★★★★★★★★」null; 더 좋은 언어는 다루지 않아도 살 수.null.

다음 방법으로 문제를 해결할 수 있습니다.

    switch(month==null?"":month)
    {
        ...
        //case "":
        default: 
            monthNumber = 0;

    }

는 않지만String.valueOf()그럼 스위치로 늘스트링을 사용할 수 있습니다.「」를 null로됩니다."null"그렇지 않으면 전달한 문자열이 반환됩니다."null"명백하게, 그러면 그것은 에 갈 것이다.default할 방법이 없다는 것입니다."null"의 「」는,null★★★★★★ 。

    String month = null;
    switch (String.valueOf(month)) {
        case "january":
            monthNumber = 1;
            break;
        case "february":
            monthNumber = 2;
            break;
        case "march":
            monthNumber = 3;
            break;
        case "null":
            monthNumber = -1;
            break;
        default: 
            monthNumber = 0;
            break;
    }
    return monthNumber;

은 왜 던지려고 하기 위한 입니다.NullPointerException

은 ada javap ap음음 음음 음음음 음 that that that that that that that 。case의 해시 코드에 근거해 선택됩니다.switch, 「NPE」가 「NPE」로 설정되어 있는 경우, 를 합니다..hashCode()는 늘 문자열로 호출됩니다.

6: invokevirtual #18                 // Method java/lang/String.hashCode:()I
9: lookupswitch  { // 3
    -1826660246: 44
     -263893086: 56
      103666243: 68
        default: 95
   }

즉, Java의 hashCode가 다른 문자열에 대해 동일한 값을 생성할 수 있는가?라는 질문에 따르면 드물지만 두 개의 케이스가 일치할 가능성이 있습니다(같은 해시 코드를 가진 두 개의 문자열). 다음 예를 참조하십시오.

    int monthNumber;
    String month = args[0];

    switch (month) {
    case "Ea":
        monthNumber = 1;
        break;
    case "FB":
        monthNumber = 2;
        break;
    // case null:
    default:
        monthNumber = 0;
        break;
    }
    System.out.println(monthNumber);

어떤 javap을 위한

  10: lookupswitch  { // 1
              2236: 28
           default: 59
      }
  28: aload_3       
  29: ldc           #22                 // String Ea
  31: invokevirtual #24                 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
  34: ifne          49
  37: aload_3       
  38: ldc           #28                 // String FB
  40: invokevirtual #24                 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
  43: ifne          54
  46: goto          59 //Default

바와 같이 1은 의 경우 1개만 됩니다."Ea" ★★★★★★★★★★★★★★★★★」"FB", 두 개의 ,, 두, 로, but가 .if각 케이스 스트링과의 일치를 체크하는 조건.이 기능을 구현하는 매우 흥미롭고 복잡한 방법!

간단히 말하면... (그리고 충분히 재미있었으면 좋겠어!!)!)

Enum은 Java1.5(2004년 7월)에 처음 도입되었으며 String의 스위치를 허용하는 버그는 오래 전(95년 10월)에 제출되었습니다.2004년 6월 버그에 대한 댓글을 보면Don't hold your breath. Nothing resembling this is in our plans.이 버그를 보류(무시)하고, 같은 해에 Java 1.5를 개시한 것 같습니다.그 결과, 0부터 시작하는 서수가 「enum」을 도입해, 열거에 대해서 null을 서포트하지 않기로(누락) 결정했습니다.나중에 Java1.7(Jul'2011)에서는 String과 같은 철학을 따랐습니다(, 바이트 코드를 생성하는 동안 hashcode() 메서드를 호출하기 전에 null 검사를 수행하지 않았습니다).

따라서 요약하면 열거형이 최초로 도입되어 순서형 선두가 0으로 실장된 것은 스위치블록의 늘값을 지원할 수 없기 때문입니다.나중에 String에서는 같은 철학(즉, null 값은 스위치블록에서 허용되지 않음)을 강제하기로 결정했습니다.

TL;DR With String은 Java 코드를 바이트 코드로 변환하는 동안 NPE(null의 해시 코드를 생성하려는 시도로 인해 발생)를 처리할 수 있었지만 결국 처리하지 않기로 결정했습니다.

참조: The BUG, Java Version이력, Java Code To Byte Code, SO

Java Docs에 따르면:

스위치는 byte, short, char 및 int 프리미티브 데이터 타입으로 동작합니다.또한 열거형(Enum Types에서 설명), String 클래스 및 특정 원시 유형을 랩하는 몇 가지 특수 클래스에도 사용할 수 있습니다.문자, 바이트, 단축 및 정수(숫자와 문자열로 설명)

★★null는 타입이 없고 어떤 인스턴스도 아니기 때문에 switch 문에서는 동작하지 않습니다.

정답은 단순히 참조 유형(박스형 프리미티브 유형 등)을 가진 스위치를 사용하는 경우 식을 언박스로 하면 NPE가 느려지기 때문에 식이 늘이면 런타임에러가 발생합니다.

따라서 케이스 null(불법)을 실행할 수 없습니다.

@Paul Bellora의 답변에 있는 https://stackoverflow.com/a/18263594/1053496의 통찰력 있는 코멘트(후드 아래...)에 동의합니다.

나는 내 경험에서 한 가지 이유를 더 찾았다.

스위치(변수)가 눌임을 의미하는 'case'가 눌일 수 있는 경우 개발자가 일치하는 'null' 케이스를 제공하는 한 문제가 없다고 주장할 수 있습니다.그러나 개발자가 일치하는 'null' 케이스를 제공하지 않으면 어떻게 됩니까?그런 다음 디폴트 케이스와 대조해야 합니다.디폴트 케이스에서는 개발자가 처리하려고 했던 것이 아닐 수 있습니다.따라서 'null'을 기본값과 일치시키면 '깜짝 동작'이 발생할 수 있습니다.따라서 'NPE'를 던지면 개발자는 모든 사례를 명시적으로 처리할 수 있습니다.저는 이 경우에 NPE를 던지는 것이 매우 사려 깊다고 생각했습니다.

Apache String Utils 클래스 사용

String month = null;
switch (StringUtils.trimToEmpty(month)) {
    case "xyz":
        monthNumber=1;  
    break;
    default:
       monthNumber=0;
    break;
}

언급URL : https://stackoverflow.com/questions/18263489/why-doesnt-string-switch-statement-support-a-null-case

반응형