为什么阿里建议对 switch 括号内的 String 变量进行判空?

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入「芋道快速开发平台」知识星球。下面是星球提供的部分资料: 

4f979f84912e0d31743f4215435169d8.gif

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro

  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud

  • 视频教程:https://doc.iocoder.cn

【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

来源:juejin.cn/post/
7295575713343537167


引言

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

490589705e6b932cb672f319798e4eed.jpeg

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

  • switch括号内的变量类型为String。

  • 此变量为外部参数时。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro

  • 视频教程:https://doc.iocoder.cn/video/

变量类型为String

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

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空指针异常~

Exception in thread "main" java.lang.NullPointerException
 at SwitchString.method(SwitchString.java:8)
 at SwitchString.main(SwitchString.java:4)

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

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

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,但是我们对其打印是没有问题的,但如果涉及到了对这个对象的某些方法或者属性的调用就会报错。

null
Exception in thread "main" java.lang.NullPointerException
 at TestNPE.main(TestNPE.java:8)

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

其实swtich是Java中的一个语法糖。

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

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

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

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,所以出现了空指针异常。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud

  • 视频教程:https://doc.iocoder.cn/video/

外部参数

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

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");
        }
    }
}
9058a80e9482f9054add74a565313dd4.jpeg

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

总结

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

  • switch括号内的变量类型为String。

  • 此变量为外部参数时。

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

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


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

63a6ca9be6e04580588f5a6bd283d967.png

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

6ce8dc3afec8ffcfe76d636d66a24039.png

87f0bfe69a18d9987c11b64d61295795.pnga2cf61ef4bc80176e20732c845f29b11.pngea170989e2f685d7145fdda614a0ff50.pngfaa091f33fa188735d3ffdebdc85b76c.png

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器学习模型机器
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值