为什么交换机(Java)会发生这种情况?

时间:2013-11-25 06:00:21

标签: java string switch-statement

很明显,switch语句可以在Java中使用字符串值,如下所示:

String s="diljit"
switch(s){
 ..
 ....}

将始终编译.. s String ....类型的对象,但另一方面开关< / strong>语句不能接受其他类的对象?为什么会发生这种情况?我将如何用合适的答案验证这个问题..

可以切换语句是否 对象

3 个答案:

答案 0 :(得分:8)

  

可以切换语句是否接受对象?

不,你不能在switch语句中使用任何任意对象。这是在语言本身中指定的。甚至{J}仅允许从Java 7开始使用String。来自JLS §14.11

  

表达式的类型必须为charbyteshortintCharacterByte,{{1} },ShortIntegerString类型(第8.9节),或发生编译时错误。

答案 1 :(得分:1)

使用hashCode比较编译带有字符串的switch语句,所以代码为:

switch(s){
    case "1":
    case "2":
    case "3":
}
编译后的

如下:

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

实际上,第7次JVM没有添加任何关于在交换机中使用字符串的具体内容。只是一个小编译技巧。可以通过hashCode()比较Strings,因为这个函数被覆盖并且基于对象的内容。此信息在编译时出现。 虽然对于Strings这样的方法是合法的,对于任意对象来说绝对是不可接受的,因为hashCode()返回一个随机数。

这就是它在字节码中的表现:

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 

使用字符串切换编译为使用整数进行切换。如果意外地两个哈希码相等,则将字符串与equals()方法进行比较。来自JVM规范的Compiling switches

答案 2 :(得分:0)

String在java中非常特殊。  String旨在介于primitiveClass之间。

允许每个primitive,java允许(来自7)String也在switch(内部使用**equals**方法)。

所以String允许切换。但不是每个Object.