今天看到阿里巴巴Java规约中规定
【控制语句2】
也许第一反应是会进default,但运行结果是抛出了空指针异常;查看一下编译后的代码就知道原因了,下面是method编译后反编译的代码:
public static void method(String param) {
byte var2 = -1;
switch(param.hashCode()) {
case 114215:
if (param.equals("sth")) {
var2 = 0;
}
break;
case 3392903:
if (param.equals("null")) {
var2 = 1;
}
}
switch(var2) {
case 0:
System.out.println("it's sth");
break;
case 1:
System.out.println("it's null");
break;
default:
System.out.println("default");
}
}
首先,其利用String的hashCode对其进行了一次switch case操作(空指针异常的原因就很明显了),得到一个var,再对var进行switch case;这很容易让人想到hash冲突如何解决?见以下代码:
case 3104:
if (b.equals("aa")) {
var4 = 1;
} else if (b.equals("bB")) {
var4 = 0;
}
使用了if 结合equals来进行操作,正确性得到保证;
首先参考官方文档对swtich 语句相关描述。
翻译如下:
switch 的表达式必须是 char, byte, short, int, Character, Byte, Short, Integer, String, 或者 enum 类型,否则会发生编译错误
同时switch 语句必须满足以下条件,否则会出现编译错误:
- 与 switch 语句关联的每个 case 都必须和 switch 的表达式的类型一致;
- 如果 switch 表达式是枚举类型,case 常量也必须是枚举类型;
- 不允许同一个 switch 的两个 case 常量的值相同;
- 和 switch 语句关联的常量不能为 null ;
- 一个 switch 语句最多有一个 default 标签。
switch 语句执行的时候,首先将执行 switch 的表达式。如果表达式为 null, 则会抛出 NullPointerException,整个 switch 语句的执行将被中断。
总结:
了解了switch对String的处理后,如果case中的选项没有出现大量的hashcode冲突的字符串时,其效率并不会被大幅降低;
switch因为会对其获取hashcode,所以不能传递null,否则会抛出NPE;
参考:
https://www.jianshu.com/p/2134d6d96df2