为什么阿里建议对 switch 括号内的 String 变量进行判空?
共 8396字,需浏览 17分钟
·
2024-08-16 14:17
来源:juejin.cn/post/7295575713343537167
👉 欢迎加入小哈的星球,你将获得: 专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍; 《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/; 截止目前,累计输出 53w+ 字,讲解图 2330+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有1900+小伙伴加入
-
引言 -
变量类型为String -
外部参数 -
总结
引言
空指针NullPointerException
可以说是开发中最经常碰到的异常了。良好的代码规范可以规避掉一些这样的异常。在《阿里巴巴规范手册》中有这样一条规范:
我们可以从这句话得出两个前置条件:
-
switch括号内的变量类型为String。 -
此变量为外部参数时。
变量类型为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,所以出现了空指针异常。
外部参数
那么为啥还要是外部参数呢?其实很简单,我们把代码修改一下:
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这种情况进行了分析,得出了两个条件:
-
switch括号内的变量类型为String。 -
此变量为外部参数时。
条件1是String类型的变量参数对象的判断是通过equals()
和hashCode()
方法来实现的。所以变量参数为null,调用这两个方法就会出现NPE。
条件2则是编译器会帮我们检查并且这是不符合语法的不能进行编译。
👉 欢迎加入小哈的星球,你将获得: 专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17..., 点击查看项目介绍; 《从零手撸:前后端分离博客项目(全栈开发)》 2期已完结,演示链接:http://116.62.199.48/; 截止目前,累计输出 53w+ 字,讲解图 2330+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,解锁全部项目,已有1900+小伙伴加入
1. 我的私密学习小圈子~
最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。
PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。
点“在看”支持小哈呀,谢谢啦