Why is this happenning with switch (Java)?

This question already has an answer here:

  • Why can't I switch on a String? 14 answers

  • Can switch statement take objects or not?

    No you can't use any arbitrary object in switch statements. This is specified in the language itself. Even String is only allowed from Java 7 onwards. From JLS §14.11:

    The type of the Expression must be char , byte , short , int , Character , Byte , Short , Integer , String , or an enum type (§8.9), or a compile-time error occurs.


    Switch statements with strings are compiled with hashCode comparison, so the code:

    switch(s){
        case "1":
        case "2":
        case "3":
    }
    

    after compilation looks like:

    switch(s.hashCode()){
        case "1".hashCode():
        case "2".hashCode():
        case "3".hashCode():
    }
    

    Actually 7th JVM did not add anything specific about working with Strings in switches. Just a little compilation trick. Its possible to compare Strings by hashCode(), because this function is overridden and is based on object's content. This information is present at compile time. While its legal for Strings such approach is absolutely unacceptable for arbitrary object, because hashCode() returns a random number.

    That's how it looks in bytecode:

    11: tableswitch   { // 49 to 51
                49: 36        // "1".hashCode() 
                50: 50        // "2".hashCode() 
                51: 64        // "3".hashCode() 
           default: 75
      }
    36: aload_2       
    37: ldc           #4                  // String 1
    39: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
    42: ifeq          75
    45: iconst_0      
    46: istore_3      
    47: goto          75
    50: aload_2       
    51: ldc           #6                  // String 2
    53: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
    56: ifeq          75
    59: iconst_1      
    60: istore_3      
    61: goto          75
    64: aload_2       
    65: ldc           #7                  // String 3
    67: invokevirtual #5                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
    70: ifeq          75
    73: iconst_2      
    74: istore_3      
    75: iload_3       
    76: tableswitch   { // 0 to 2
             0: 104
             1: 104
             2: 104
       default: 104
    }
    104: return 
    

    Switch with Strings is compiled to switch with ints. If accidentally two hash codes are equal, strings are compared with equals() method. Compiling switches from JVM specification.


    String is very special in java. String is designed to be in between a primitive and a Class .

    Making available to each primitive , java allowing (from 7) String also in switch (using **equals** method internally).

    So String is allowing in switch. But not the every Object.

    链接地址: http://www.djcxy.com/p/84512.html

    上一篇: 在Switch语句中使用String?

    下一篇: 为什么这是交换(Java)发生的?