打破你的认知!Java空指针居然还能这样玩,90%人不知道…
相信在座的各位都遇到过空指针异常,不甚其烦,本文不是教你避免空指针,而是一些对空指针其他方面的理解。
本文可能有点另类,也可能会打破你对空指针的认知。
1、null.method() 空指针?
我们知道调用一个对象的方法,如果对象为 null 肯定会报空指针错误的,但你确定一定会吗?
不一定!
来看下面的示例:
/**
* 访问静态方法
* @from 微信公众号:Java技术栈
*/
private static void test() {
NullTest nullTest = null;
// hello
nullTest.test1("hello");
}
/**
* @from 微信公众号:Java技术栈
* 关注获取更多好玩的 Java 技术干货
*/
private static void test1(String text) {
System.out.println(text);
}
如果 null 对象指向该类型的静态方法,不但不会报空指针错误,而且还会运行正常,是不是很6?
因为静态方法不属于任何对象,它属于类本身的,相当于直接调用类的静态方法。
2、拆箱空指针
是的,大家要注意拆箱引发的空指针风险,不知道的赶紧往下看,来看下面的例子:
/**
* 拆箱
* @from 微信公众号:Java技术栈
*/
private static void test() {
Integer i = null;
// //NullPointerException
int ii = i;
System.out.println(ii);
}
拆箱如果为 null 时,引发空指针错误。
这个在最新的《阿里巴巴开发手册》中也提到了,链接里面举了三目运算符拆箱时的空指针问题,没看过的可以点进去看,这里就不具体展开了。获取这份最新开发手册,请在公众号Java技术栈回复手册。
3、运算符空指针
大家要注意了,运算符使用不当也会引发空指针异常,来看下面的例子:
/**
* 运算符
* @from 微信公众号:Java技术栈
*/
private static void test5() {
Integer i = null;
Integer j = null;
// true
System.out.println(i == j);
// false
System.out.println(i != j);
// NullPointerException
System.out.println(i > j);
// NullPointerException
System.out.println(i < j);
//NullPointerException
System.out.println(i & j);
}
例子很明显吧,使用 ==、!= 运算符比较是否相等不会有问题,但使用 > < & 等需要计算的运算符就会引起空指针异常。
4、xxx == null引发空指针?
经常看博客或者身边的同事说,字符串比较,常量要放前面,为了避免空指针风险,这个对于 equals 来说确实要这样写。
但是,居然还有人说,甚至也有很多人也是这么在写, == 比较,null 也要放前面,这也是为了避免空指针?还是为了避免啥风险?
首先要搞清楚为什么有 null == xxx 这个写法?
这个写法的初衷是 C++ 为了避免逻辑错误的,因为 C++ 写 if(xxx = NULL) 是不会报编译错误的(变量赋值,永远为真),而写 if(NULL = xxx) 是会有编译错误的。
所以在 C++ 建议把 NULL 放在前面,是为了避免程序员把 == 写成 = 引起的逻辑错误的。
而在 Java 里面,if(xxx = null) 是有编译错误提示的:

所以 Java 中不会出现 C++ 的没有编译提示而导致的逻辑问题,所以 Java 中的 xxx == null 和 null == xxx 是等价的,null 放前面也是没有任何意义的。
我们甚至还可以在 Java 中写 null == null 的判断,这也是 OK 的,完全没问题的。
下面是完整的示例:
/**
* 运算符
* @from 微信公众号:Java技术栈
*/
private static void test() {
Integer i = null;
// i is null
if (null == i){
System.out.println("i is null");
}
// i is null
if (i == null){
System.out.println("i is null");
}
// i == j
Integer j = null;
if (i == j){
System.out.println("i == j");
}
// 编译错误
if (i = null){
System.out.println("i is null");
}
}
有没有小伙伴也被这个说法迷糊过?
5、null instanceof 空指针?
null instanceof 会发生空指针异常么?
不会!
来看下面的示例:
/**
* instanceof
* @from 微信公众号:Java技术栈
*/
private static void test() {
Integer i = null;
// false
if(i instanceof Number){
System.out.println("true");
} else {
System.out.println("false");
}
// false
if(null instanceof Number){
System.out.println("true");
} else {
System.out.println("false");
}
}
如果为 null, instanceof 右边可以是任意引用类型,但结果始终输出 false,因为 null 不是任何对象的引用。
总结
好了,今天栈长的分享就到这了,又涨姿势了吧?
另外,之前这篇《避免空指针的 5 个案例》也不错的,没看过的值得阅读一下。
大家还知道哪些空指针的骚操作?欢迎留言分享哦!~
最后,感谢阅读,原创不易,各位老铁们,给个在看、转发下吧!
推荐去我的博客阅读更多:
2.Spring MVC、Spring Boot、Spring Cloud 系列教程
3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程
觉得不错,别忘了点赞+转发哦!
打破你的认知!Java空指针居然还能这样玩,90%人不知道…的更多相关文章
- Java 12 骚操作, String居然还能这样玩!
Java 13 都快要来了,12必须跟栈长学起! Java 13 即将发布,新特性必须抢先看! 栈长之前在Java技术栈微信公众号分享过<Java 11 已发布,String 还能这样玩!> ...
- Java 12 骚操作, 文件比对居然还能这样玩!
Java 13 都快要来了,12必须跟栈长学起! Java 13 即将发布,新特性必须抢先看! 之前分享了一些 Java 12 的骚操作,今天继续,今天要分享的是 Java 12 中的文件比对骚操作. ...
- Java 12 骚操作, switch居然还能这样玩!
Java 13 都快要来了,12必须跟栈长学起! Java 13 即将发布,新特性必须抢先看! Java 12 中对 switch 的语法更友好了,建议大家看下栈长在Java技术栈微信公众号分享的&l ...
- Java“微服务”还能这么玩!
"微服务"加个引号是因为这不是传统定义的微服务架构,顶多算是"小服务"架构,因为服务实例由集群节点统一加载,非独立部署.下面以图说明一下服务调用流程. 一. ...
- Java 11 已发布,String 还能这样玩!
在文章<Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码>中,我有介绍到 Java 11 的八个新特性,其中关于 String 加强部分,我觉得有点意思,这里单独再拉出来 ...
- Android事件总线还能怎么玩?
作者简介:何红辉,Android工程师,现任职于友盟. 顾名思义,AndroidEventBus是一个Android平台的事件总线框架,它简化了Activity.Fragment.Service等组件 ...
- Apache DolphinScheduler 需要的sudo,还可以这么玩,长见识了!
Apache DolphinScheduler(incubator)需要的sudo,还可以这么玩,长见识了! 在新一代大数据任务调度 - Apache DolphinScheduler(以下简称dol ...
- 【Java学习笔记之二十五】初步认知Java内部类
可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一个非常有用的特性但又比较难理解使用的特性(鄙人到现在都没有怎么使用过内部类,对内部类也只是略知一二). 第一次见面 内部类我们从外面 ...
- java系列: 对不起,JavaFX——Java 8目前还不能救你(zz)
JavaFX 是SUN公司在2007年JavaOne大会上首次对外公布的以Java为基础构建的富客户端平台,更让开发者印象比较深刻的则是其背后的JavaFX开发团队,仅仅在两年的时间就从1.0版本完善 ...
随机推荐
- pytest框架的安装与使用
pytest框架的安装与使用 一,pytest了解 pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高. ...
- From 表单序列化为json对象(代码片段)
$.fn.serializeJson=function(){ var serializeObj={}; var array=this.serializeArray(); $(array).each(f ...
- EF Code 如何输出sql语句
首先写拷贝下面类 public class EFLoggerProvider : ILoggerProvider { public ILogger CreateLogger(string catego ...
- windy数(数位dp)
https://www.luogu.com.cn/blog/virus2017/shuweidp https://www.luogu.com.cn/problem/P2657 #include < ...
- 【Unity3D】简单常用的功能实现1——鼠标点击实现移动
[鼠标点击实现移动] 第一步,在要移动的GameObject的Inspector面板中添加角色控制器组件并调整参数. 参数的调整可以依照Scene面板,如下图的绿色线框(角色控制器组件是一种胶囊形状的 ...
- Mybatis(五)Spring整合Mybatis之mapper动态代理开发
要操作的数据库: IDEA创建的Java工程,目录结构如下: 一.导包 1.spring的jar包 2.Mybatis的jar包 3.Spring+mybatis的整合包. 4.Mysql的数据库驱动 ...
- 删除表中重复数据,只删除重复数据中ID最小的
delete t_xxx_user where recid in ( select recid from t_xxx_user where recid in ( select min(recid) f ...
- shell 中的${},##, %% , :- ,:+, ? 的使用
假设我们定义了一个变量为:file=/dir1/dir2/dir3/my.file.txt 可以用${ }分别替换得到不同的值:${file#*/}:删掉第一个/ 及其左边的字符串:dir1/dir2 ...
- MyBatis Plus 导入IdType失败
import com.baomidou.mybatisplus.annotation.IdType; 修正Entity模板IdType引入包名到com.baomidou.mybatisplus.enu ...
- Spring集成Quartz定时任务
1.导入jar包 2.配置applicationContext.xml文件 <!-- 任务调度1 --> <!-- bean id="simpleJob" cla ...