【强制】当 switch 括号内的变量类型为 String 并且此变量为外部参数时,必须先进行 null 判断。
反例:如下的代码输出是什么?package cn.shentianlan.studytest.common; public class SwitchString { public static void main(String[] args) { method(null); } public static void method(String param) { switch (param) { // 肯定不是进入这里 case "sth": System.out.println("it's sth"); break; // 也不是进入这里 case "null": System.out.println("it's null"); break; // 也不是进入这里 default: System.out.println("default"); } } }
-------来自阿里巴巴《Java开发手册》泰山版
上述示例代码直接运行会报NPE(空指针异常)
直接通过IDEA查看其SwitchString.class文件反编译后的代码如下所示
package cn.shentianlan.studytest.common;
public class SwitchString {
public SwitchString() {
}
public static void main(String[] args) {
method((String)null);
}
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类型作为switch语句的判断数据,会先调用hashCode()方法,通过String类型的哈希值进行第一次比较,所以当String类型为null时,则会报NPE
测试其他:
package cn.shentianlan.studytest.common;
public class SwitchTest {
public static void main(String[] args) {
switchTestMethon2(null);
}
public static void switchTestMethon(String value){
switch (value){
case "aaa":
System.out.println("I'm aaa");
break;
case "bbb":
System.out.println("I'm bbb");
break;
default:
System.out.println("I don't know ");
}
}
public static void switchTestMethon2(Integer value){
switch (value){
case 10:
System.out.println("I'm 10");
break;
case 20:
System.out.println("I'm 20");
break;
default:
System.out.println("I don't know ");
}
}
}
使用jad 进行反编译:
package cn.shentianlan.studytest.common;
import java.io.PrintStream;
public class SwitchTest
{
public SwitchTest()
{
}
public static void main(String args[])
{
switchTestMethon2(null);
}
public static void switchTestMethon(String value)
{
String s = value;
byte byte0 = -1;
switch(s.hashCode())
{
case 96321:
if(s.equals("aaa"))
byte0 = 0;
break;
case 97314:
if(s.equals("bbb"))
byte0 = 1;
break;
}
switch(byte0)
{
case 0: // '\0'
System.out.println("I'm aaa");
break;
case 1: // '\001'
System.out.println("I'm bbb");
break;
default:
System.out.println("I don't know ");
break;
}
}
public static void switchTestMethon2(Integer value)
{
switch(value.intValue())
{
case 10: // '\n'
System.out.println("I'm 10");
break;
case 20: // '\024'
System.out.println("I'm 20");
break;
default:
System.out.println("I don't know ");
break;
}
}
}