相信在座的各位都遇到过空指针异常,不甚其烦,本文不是教你避免空指针,而是一些对空指针其他方面的理解。

本文可能有点另类,也可能会打破你对空指针的认知。

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 == nullnull == 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 个案例》也不错的,没看过的值得阅读一下。

大家还知道哪些空指针的骚操作?欢迎留言分享哦!~

最后,感谢阅读,原创不易,各位老铁们,给个在看、转发下吧!

推荐去我的博客阅读更多:

1.Java JVM、集合、多线程、新特性系列教程

2.Spring MVC、Spring Boot、Spring Cloud 系列教程

3.Maven、Git、Eclipse、Intellij IDEA 系列工具教程

4.Java、后端、架构、阿里巴巴等大厂最新面试题

觉得不错,别忘了点赞+转发哦!

打破你的认知!Java空指针居然还能这样玩,90%人不知道…的更多相关文章

  1. Java 12 骚操作, String居然还能这样玩!

    Java 13 都快要来了,12必须跟栈长学起! Java 13 即将发布,新特性必须抢先看! 栈长之前在Java技术栈微信公众号分享过<Java 11 已发布,String 还能这样玩!> ...

  2. Java 12 骚操作, 文件比对居然还能这样玩!

    Java 13 都快要来了,12必须跟栈长学起! Java 13 即将发布,新特性必须抢先看! 之前分享了一些 Java 12 的骚操作,今天继续,今天要分享的是 Java 12 中的文件比对骚操作. ...

  3. Java 12 骚操作, switch居然还能这样玩!

    Java 13 都快要来了,12必须跟栈长学起! Java 13 即将发布,新特性必须抢先看! Java 12 中对 switch 的语法更友好了,建议大家看下栈长在Java技术栈微信公众号分享的&l ...

  4. Java“微服务”还能这么玩!

      "微服务"加个引号是因为这不是传统定义的微服务架构,顶多算是"小服务"架构,因为服务实例由集群节点统一加载,非独立部署.下面以图说明一下服务调用流程. 一. ...

  5. Java 11 已发布,String 还能这样玩!

    在文章<Java 11 正式发布,这 8 个逆天新特性教你写出更牛逼的代码>中,我有介绍到 Java 11 的八个新特性,其中关于 String 加强部分,我觉得有点意思,这里单独再拉出来 ...

  6. Android事件总线还能怎么玩?

    作者简介:何红辉,Android工程师,现任职于友盟. 顾名思义,AndroidEventBus是一个Android平台的事件总线框架,它简化了Activity.Fragment.Service等组件 ...

  7. Apache DolphinScheduler 需要的sudo,还可以这么玩,长见识了!

    Apache DolphinScheduler(incubator)需要的sudo,还可以这么玩,长见识了! 在新一代大数据任务调度 - Apache DolphinScheduler(以下简称dol ...

  8. 【Java学习笔记之二十五】初步认知Java内部类

    可以将一个类的定义放在另一个类的定义内部,这就是内部类. 内部类是一个非常有用的特性但又比较难理解使用的特性(鄙人到现在都没有怎么使用过内部类,对内部类也只是略知一二). 第一次见面 内部类我们从外面 ...

  9. java系列: 对不起,JavaFX——Java 8目前还不能救你(zz)

    JavaFX 是SUN公司在2007年JavaOne大会上首次对外公布的以Java为基础构建的富客户端平台,更让开发者印象比较深刻的则是其背后的JavaFX开发团队,仅仅在两年的时间就从1.0版本完善 ...

随机推荐

  1. java 基本语法(十七)Lambda (四)构造器引用与数组引用

    1.构造器引用格式:类名::new 2.构造器引用使用要求:和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致.抽象方法的返回值类型即为构造器所属的类的类型 3.构造器引用举例: / ...

  2. 数据可视化之DAX篇(十三)熟练使用FORMAT函数,轻松自定义数据格式

    https://zhuanlan.zhihu.com/p/64420449 在进行数据分析时,需要对某个数据进行格式调整的情形经常会遇到,在DAX中有一个专门进行格式调整的函数:FORMAT. 其实对 ...

  3. Android 高德地图 java.lang.UnsatisfiedlinkError Native method not found: com.autonavi.amap.mapcore.MapCore.nativeNewInstance:(Ljava/lang/String;)

    在Android项目中引用高德地图,程序运行时出现上述问题,如果引用了Map3D的jar包,则需要在引入Jar文件的同时引入so文件,在高德地图的demo中,找到so文件: 然后将其复制到jniLib ...

  4. git的撤销、删除和版本回退

    目录 备注: 知识点: 查看git仓库的状态 查看历史记录. 版本回退 备注: 本文参考于廖雪峰的博客Git教程.依照其博客进行学习和记录,感谢其无私分享,也欢迎各位查看原文. 知识点: 1.git ...

  5. 生产日志文件太大NotePad++无法打开

    问题1:NotePad++无法打开 解决方式:下载软件 LogView Pro ,用 LogView Pro打开 https://download.csdn.net/download/u0145212 ...

  6. [Qt插件]-01Qt插件&&提升部件(自定义控件)

    本篇的文档为:How to Create Qt Plugins https://doc.qt.io/qt-5/plugins-howto.html   前言 Qt插件(Qt Plugin)就是一个共享 ...

  7. 事件循环 event loop 究竟是什么

    事件循环 event loop 究竟是什么 一些概念 浏览器运行时是多进程,从任务管理器或者活动监视器上可以验证. 打开新标签页和增加一个插件都会增加一个进程,如下图:  浏览器渲染进程是多线程,包 ...

  8. Ubuntu安装Redis过程完整笔记

    在阿里云与百度云均已经安装成功~~ 下载文件 切换路径设置下载存放地址 cd /home 下载安装包(http://download.redis.io/releases建议下载最新稳定版本) sudo ...

  9. #python自动化测试#代码执行时间测量模块timeit

    1. timeit模块timeit模块可以用来测试一小段python代码的执行速度 class timeit.Timer(stmt = 'pass',setup = 'pass',timer=< ...

  10. python txt装换成excel

    工作中,我们需要经常吧一些导出的数据文件,例如sql查出来的结果装换成excel,用文件发送.这次为大家带上python装换excel的脚本 记得先安装wlwt模块,适用版本,python2-3 #c ...