为什么阿里巴巴说要对switch括号内的String变量进行判空?

引言

空指针NullPointerException可以说是开发中最经常碰到的异常了。良好的代码规范可以规避掉一些这样的异常。在《阿里巴巴规范手册》中有这样一条规范:

我们可以从这句话得出两个前置条件:

  1. switch括号内的变量类型为String。
  2. 此变量为外部参数时。

变量类型为String

你知道这行代码输出什么吗?

java 复制代码
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");
        }
    }
}

如果我们不看上面的注释,你会认为程序会打印出哪句话呢?我们点击运行,报了NullPointerException空指针异常~

txt 复制代码
Exception in thread "main" java.lang.NullPointerException
	at SwitchString.method(SwitchString.java:8)
	at SwitchString.main(SwitchString.java:4)

很奇怪,为啥会空指针呢? 你可能会说第8行param为空,所以空指针了。虽然这样理解也没问题。

我们要知道,NPE异常是代码中使用了这个对象的某些方法或者属性,而这个对象为空所以就会抛出异常。例如以下代码

java 复制代码
public class TestNPE {
    private int id;

    public static void main(String[] args) {
        TestNPE testNPE = null;
        System.out.println(testNPE);
        System.out.println(testNPE.id);
    }
}

我们点击运行可以得知。虽然testNPE这个对象为null,但是我们对其打印是没有问题的,但如果涉及到了对这个对象的某些方法或者属性的调用就会报错。

txt 复制代码
null
Exception in thread "main" java.lang.NullPointerException
	at TestNPE.main(TestNPE.java:8)

而我们上面那个例子,它是在哪里使用了这个对象呢?

其实swtich是Java中的一个语法糖。(更多详情可以看以前的文章juejin.cn/post/729516...

JDK7之前switch本身只支持基本类型,JDK7开始支持String。

Java中的switch自身原本就支持基本类型。比如intchar等。对于int类型,直接进行数值的比较。对于char类型则是比较其ascii码。所以,对于编译器来说,switch中其实只能使用整型,任何类型的比较都要转换成整型。比如byteshortchar(ackii码是整型)以及int

我们将上面的代码进行反编译可以得到

java 复制代码
public class 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");
      }

   }
}

字符串的switch是通过equals()hashCode()方法来实现的。 由于调用了这两个方法,而param为null,所以出现了空指针异常。

外部参数

那么为啥还要是外部参数呢?其实很简单,我们把代码修改一下:

java 复制代码
public class SwitchString {

    public static void main(String[] args) {
        switch (null) {
            // 肯定不是进入这里
            case "sth":
                System.out.println("it's sth");
                break;
            // 也不是进入这里
            case "null":
                System.out.println("it's null");
                break;
            // 也不是进入这里
            default:
                System.out.println("default");
        }
    }
}

这样的代码是会报错提示的且编译是无法通过。~~

总结

我们对switch这种情况进行了分析,得出了两个条件:

  1. switch括号内的变量类型为String。
  2. 此变量为外部参数时。

条件1是String类型的变量参数对象的判断是通过equals()hashCode()方法来实现的。所以变量参数为null,调用这两个方法就会出现NPE。

条件2则是编译器会帮我们检查并且这是不符合语法的不能进行编译。

相关推荐
Han.miracle1 天前
《Spring MVC 响应机制综合实践:页面、数据、JSON 与响应配置》
java·spring·springboot
xiaoxue..1 天前
列表转树结构:从扁平列表到层级森林
前端·javascript·算法·面试
JHC0000001 天前
dy直播间评论保存插件
java·后端·python·spring cloud·信息可视化
SuperherRo1 天前
JAVA攻防-FastJson专题&面试不出网利用&BCEL字节码&C3P0二次&Impl链&延时判断
java·fastjson·不出网
TH_11 天前
18、删除WPSOfficeWord文档中的空白页
java
一雨方知深秋1 天前
数组定义及访问
java·数组·二维数组·for·length·定义访问
alanesnape1 天前
Java异常处理详解:Exception、ArithmeticException、FileNotFoundException
java·开发语言
while(1){yan}1 天前
数据链路层与物理层
java·网络·网络协议
野蛮人6号1 天前
黑马微服务 p23Docker02 docker的安装 如何正确安装docker,黑马微服务给的文档不行了,如何正确找到解决方法
java·docker·微服务·架构
武子康1 天前
Java-206 RabbitMQ 发布订阅(fanout)Java 实战:推/拉模式、ACK 与绑定排错全梳理
java·分布式·消息队列·rabbitmq·rocketmq·java-rabbitmq·mq