打破你的认知!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) 是有编译错误提示的:


image.png


所以 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 不是任何对象的引用。



相关文章
|
7月前
|
存储 Oracle Java
Java11--ZGC--权衡--ZGC--GC术语--着色指针--多重映射--读屏障标记--重定位
Java11--ZGC--权衡--ZGC--GC术语--着色指针--多重映射--读屏障标记--重定位
136 0
|
6月前
|
存储 小程序 Java
打破传统,Java 变量与常量让你重新认识编程的魅力!
【6月更文挑战第14天】Java编程中的变量与常量赋予程序灵活性和动态性。变量如魔法盒子,其值可变,提供程序的适应性;常量则如灯塔,值恒定,确保稳定性。两者结合构建复杂程序,变量用于处理数据,常量定义规则。在项目中,规范管理变量和常量能提升代码可读性和维护性。无论是小游戏还是复杂系统,它们都是不可或缺的工具,激发编程的无限可能。
29 1
java.lang.NullPointerExceptionMybatisPlus出现,测试,java.lang.NullPointe,空指针异常,public方法少写了一个字段,没加注解
java.lang.NullPointerExceptionMybatisPlus出现,测试,java.lang.NullPointe,空指针异常,public方法少写了一个字段,没加注解
|
6月前
|
Java 数据安全/隐私保护
Java 封装:打破传统,创新你的编程思维!
【6月更文挑战第16天】Java中的封装是将数据和操作数据的方法封装在类中,隐藏内部细节,通过公共接口交互。这样保证了数据安全,降低了耦合度,便于验证(如`Shape`类中构造函数的类型检查)和控制(如`setType`方法中添加额外操作)。封装使代码更清晰、可维护,鼓励创新编程思维。
50 11
|
6月前
|
Java
2022蓝桥杯大赛软件类国赛Java大学B组 左移右移 空间换时间+双指针
2022蓝桥杯大赛软件类国赛Java大学B组 左移右移 空间换时间+双指针
49 3
|
5月前
|
缓存 Java 数据库连接
Java演进问题之指针的间接获取现在对性能的影响变得更大如何解决
Java演进问题之指针的间接获取现在对性能的影响变得更大如何解决
|
7月前
|
存储 Java 开发者
探索Java开发中触发空指针异常的场景
作为一名后端开发者在Java编程的世界中,想必大家对空指针并不陌生,空指针异常是一种常见而又令人头疼的问题,它可能会在我们最不经意的时候突然出现,给我们的代码带来困扰,甚至导致系统的不稳定性,而且最可怕的是有时候不能及时定位到它的具体位置。针对这个问题,我们需要深入了解触发空指针异常的代码场景,并寻找有效的方法来识别和处理这些异常情况,而且我觉得空指针异常是每个Java开发者都可能面临的挑战,但只要我们深入了解它的触发场景,并采取适当的预防和处理措施,我们就能够更好地应对这个问题。那么本文就来分享一下实际开发中一些常见的触发空指针异常的代码场景,并分享如何有效地识别和处理这些异常情况。
108 1
探索Java开发中触发空指针异常的场景
|
7月前
|
存储 Java 测试技术
滚雪球学Java(16):玩转JavaSE-do-while循环语句:打破传统思维模式
【4月更文挑战第5天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
67 7
滚雪球学Java(16):玩转JavaSE-do-while循环语句:打破传统思维模式
|
6月前
|
SQL Java 数据库连接
打破瓶颈:利用Java连接池技术提升数据库访问效率
【6月更文挑战第24天】Java连接池优化数据库访问性能,减少资源消耗。原理是预创建数据库连接池,复用连接而非频繁建立断开。优势包括性能提升、资源节约和增强稳定性。示例使用HikariCP配置连接池,动态获取和释放连接。通过连接池技术,应用能更高效地处理数据库操作。
44 0
|
7月前
|
安全 Java
Java为什么不让用指针?
总之,Java的设计目标之一是提供一个安全、稳定和易于开发的平台,通过禁止直接使用指针来实现这些目标。虽然指针可以提供更大的灵活性,但也带来了许多潜在的问题和安全风险。因此,Java采用了更高级的内存管理和安全性机制,以减少这些问题的发生。
78 1
下一篇
DataWorks