Java 7 String switch反编译:意外指令
我已经反编译了一个使用新的Java 7字符串切换function的非常简单的类。
class上:
public class StringSwitch { public static void main(String[] args) { final String color = "red"; switch (color) { case "red": System.out.println("IS RED!"); break; case "black": System.out.println("IS BLACK"); break; case "blue": System.out.println("IS BLUE"); break; case "green": System.out.println("IS GREEN"); break; } } }
对这个类运行Java 7“javap”,会生成一组有趣的指令( 这里提供了完整的反汇编代码):
public static void main(java.lang.String[]); flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=4, args_size=1 ... 12: lookupswitch { // 4 112785: 56 3027034: 84 93818879: 70 98619139: 98 default: 109 } 56: aload_2 57: ldc #2 // String red ... 110: tableswitch { // 0 to 3 0: 140 1: 151 2: 162 3: 173 default: 181 } 140: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream; 143: ldc #9 // String IS RED! ... 181: return
“LOOKUPSWITCH”是一个指令,当switch case稀疏时可以替换TABLESWITCH,这是“switch”语句的默认指令。
所以,问题是,为什么我们看到“LOOKUPSWITCH”后跟“TABLESWITCH”?
谢谢卢西亚诺
使用switch中的字符串查找正确的case语句是一个两步过程。
- 计算switch字符串的hashcode并在case语句中查找’hashcode match’,这是通过LOOKUPSWITCH完成的。 注意LOOKUPSWITCH下的大整数,这些是case语句中字符串的哈希码。
- 现在2个字符串可以具有相同的哈希码,但不太可能。 因此,仍然必须进行实际的字符串比较。 因此,一旦匹配哈希码,就将交换字符串与匹配的case语句中的字符串进行比较。 LOOKUPSWITCH和TABLESWITCH之间的指令就是这样做的。 确认匹配后,将通过TABLESWITCH到达匹配的case语句的代码。
另请注意,指定您使用的编译器是有用的 – javac或ECJ (Java的Eclipse编译器)。 两个编译器都可能以不同方式生成字节码。
- 使用JavaMail创建带附件的EML文件
- 在filter中访问spring boot数据jpa实体
- 迭代时出现Java“ConcurrentModificationException”运行时错误.next()
- 从Java的processbuilder执行的ffmpeg不会在Windows 7下返回
- Maven依赖项未添加到WEB-INF / lib
- 无法解析org.springframework.transaction.annotation.Transactional的依赖项
- 如何在Java applet中正确指定代码库和存档?
- 如何使用Java编辑文件对象中的XML节点
- 为什么这些字符串的str == str.intern()结果不同?