0
点赞
收藏
分享

微信扫一扫

关于java的switch接收字符串底层实现逻辑

看一段代码,这是一道试题,思考一下,结果是什么?为什么?

package cn.com.suntree.utils.myself;

public class SwitchTest {
public static void main(String[] args) {

String paramStr = null;

switch (paramStr){
case "boy":

break;
case "girl":
System.out.println("is a girl ");
break;

case "null":
System.out.println("is a null ");
break;

default:
System.out.println("is a nothing ");
}
}
}

我们知道,在jdk1.7之前,switch只接收一个整型表达式,后面扩展了,支持字符串

怎么做到的,由于switch不是方法,没法直接看源码,我们将代码反编译来看看

找到字节码所在文件,用java自带命令

javap -c SwitchTest >switch.dcmp

关于java的switch接收字符串底层实现逻辑_后端
获取到反编译代码

Compiled from "SwitchTest.java"
public class cn.com.suntree.utils.myself.SwitchTest {
public cn.com.suntree.utils.myself.SwitchTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return

public static void main(java.lang.String[]);
Code:
0: aconst_null
1: astore_1
2: aload_1
3: astore_2
4: iconst_m1
5: istore_3
6: aload_2
7: invokevirtual #2 // Method java/lang/String.hashCode:()I
10: lookupswitch { // 3

97740: 44

3173020: 58

3392903: 72
default: 83
}
44: aload_2
45: ldc #3 // String boy
47: invokevirtual #4 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
50: ifeq 83
53: iconst_0
54: istore_3
55: goto 83
58: aload_2
59: ldc #5 // String girl
61: invokevirtual #4 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
64: ifeq 83
67: iconst_1
68: istore_3
69: goto 83
72: aload_2
73: ldc #6 // String null
75: invokevirtual #4 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
78: ifeq 83
81: iconst_2
82: istore_3
83: iload_3
84: tableswitch { // 0 to 2

0: 112

1: 115

2: 126
default: 137
}
112: goto 145
115: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
118: ldc #8 // String is a girl
120: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
123: goto 145
126: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
129: ldc #10 // String is a null
131: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
134: goto 145
137: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
140: ldc #11 // String is a nothing
142: invokevirtual #9 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
145: return
}

指令看不懂没关系,能看懂这句就行
关于java的switch接收字符串底层实现逻辑_后端_02
也就是说,虽然switch能接收String字符串,但在jvm的实现时,还是取了字符串的hashCode来进行操作

字符串的hashCode方法
关于java的switch接收字符串底层实现逻辑_java_03
它返回的还是一个int类型的整数,委婉的转换成了int

所以回到问题,我们的paramStr为null对象,那自然在做 hashCode()是会报空指针异常
关于java的switch接收字符串底层实现逻辑_java_04

运行一下结果,完全符合预期

关于java的switch接收字符串底层实现逻辑_后端_05
所以关于switch接收字符串能运行的原因,你明白了吗?


举报

相关推荐

0 条评论