我是靠谱客的博主 怕孤单狗,最近开发中收集的这篇文章主要介绍JAVA陷阱---三元表达式潜藏的坑,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

当熟悉的三元表达式遇到装/拆箱发生了未预料到的NPE 以下代码都是在 jdk 1.8.0_172 版本下运行

java代码如下,注释位置会抛出NPE:

public class TestThree {
    public static void main(String[] args) {
        Double a = 1D;
        Double b = 2D;
        Double c = null;

        Double d = false ? a*b : c; // 这里会抛出NPE
        System.out.println("finished");
    }
}

猜测由于a*b,Double都进行了拆箱,c因为是null,进行拆箱时就抛出了NPE,为了验证,我们使用javap -c命令看下简单的字节码信息

如上图所示,第12--21行即c的操作过程,可以看出第18行Double.doubleValue获取c的小double值就是抛出NPE的罪魁祸首。

但是有个疑问,很明显可以看出,经过javac的优化,ab根本不会执行,a、b也都没有拆箱的操作,为什么要对c进行拆箱呢,直接将null赋值给d不是更简捷,仅仅因为代码中使用了ab进行乘法运算就导致了c的拆箱吗? 我们来做个验证:

public class TestThree {
    public static void main(String[] args) {
        //Double a = 1D;
        //Double b = 2D;
        Double c = null;

        Double d = false ? null : c; // 这里不会抛出NPE
        System.out.println("finished");
    }
}

上面的代码能够成功运行,我们来看下反编译出的字节码内容

可以看到确实没有对c的Double.valueOf方法的调用,之前对c的拆箱确实是由于a*b运算导致的。

至此,我们可以得出一个猜想,在三元表达式中,如果一个结果执行了数学运算,即使表达式的判断条件短路了此运算,另外一个结果也会由于拆箱而可能导致NPE的发生

最后留一个问题,下面的代码是否会抛出NPE,其反编译后的代码又会是什么样子的,想象一下~

public class TestThree {
    public static void main(String[] args) {
        Double a = 1D;
        Double b = 2D;
        Double c = null;

        Double d = false ? 1 : c; // 这里会不会抛出NPE???
        System.out.println("finished");
    }
}

转载于:https://my.oschina.net/u/580449/blog/3051244

最后

以上就是怕孤单狗为你收集整理的JAVA陷阱---三元表达式潜藏的坑的全部内容,希望文章能够帮你解决JAVA陷阱---三元表达式潜藏的坑所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部