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

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

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. pytest框架的安装与使用

    pytest框架的安装与使用 一,pytest了解 pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高. ...

  2. From 表单序列化为json对象(代码片段)

    $.fn.serializeJson=function(){ var serializeObj={}; var array=this.serializeArray(); $(array).each(f ...

  3. EF Code 如何输出sql语句

    首先写拷贝下面类 public class EFLoggerProvider : ILoggerProvider { public ILogger CreateLogger(string catego ...

  4. windy数(数位dp)

    https://www.luogu.com.cn/blog/virus2017/shuweidp https://www.luogu.com.cn/problem/P2657 #include < ...

  5. 【Unity3D】简单常用的功能实现1——鼠标点击实现移动

    [鼠标点击实现移动] 第一步,在要移动的GameObject的Inspector面板中添加角色控制器组件并调整参数. 参数的调整可以依照Scene面板,如下图的绿色线框(角色控制器组件是一种胶囊形状的 ...

  6. Mybatis(五)Spring整合Mybatis之mapper动态代理开发

    要操作的数据库: IDEA创建的Java工程,目录结构如下: 一.导包 1.spring的jar包 2.Mybatis的jar包 3.Spring+mybatis的整合包. 4.Mysql的数据库驱动 ...

  7. 删除表中重复数据,只删除重复数据中ID最小的

    delete t_xxx_user where recid in ( select recid from t_xxx_user where recid in ( select min(recid) f ...

  8. shell 中的${},##, %% , :- ,:+, ? 的使用

    假设我们定义了一个变量为:file=/dir1/dir2/dir3/my.file.txt 可以用${ }分别替换得到不同的值:${file#*/}:删掉第一个/ 及其左边的字符串:dir1/dir2 ...

  9. MyBatis Plus 导入IdType失败

    import com.baomidou.mybatisplus.annotation.IdType; 修正Entity模板IdType引入包名到com.baomidou.mybatisplus.enu ...

  10. Spring集成Quartz定时任务

    1.导入jar包 2.配置applicationContext.xml文件 <!-- 任务调度1 --> <!-- bean id="simpleJob" cla ...