理解下这句话,JLS 的规范是如果第二和第三位操作数分别是基本类型和包装类型,那么要求返回值是基本类型 。那如果你自己写的代码返回值是包装类型,那么编译器为了满足 JLS 规范,其实是会自动做一个拆箱的
简单总结:只要表达式 1 和表达式 2 的类型有一个是基本类型一个是包装类型,就会做触发类型对齐的拆箱操作 。
下面再列举几个例子加深下理解:
boolean flag = true;boolean simpleBoolean = false;Boolean objectBoolean = Boolean.FALSE;
当第二位和第三位表达式都是包装类,表达式返回值也为包装类,编译器不需要做拆箱操作Boolean x1 = flag ? objectBoolean : objectBoolean;//反编译后代码(不需要做任何特殊操作)Boolean x1 = flag ? objectBoolean : objectBoolean;
当第二位和第三位表达式都为基本类型时,表达式返回值也为基本类型,编译器不需要做拆箱操作boolean x2 = flag ? simpleBoolean : simpleBoolean;//反编译后代码(不需要做任何特殊操作)boolean x2 = flag ? simpleBoolean : simpleBoolean;
当第二位和第三位表达式中一个为基本类型另一个为包装类型时,表达式返回值为基本类型,编译器需要做拆箱操作:boolean x3 = flag ? objectBoolean : simpleBoolean;//反编译后代码(需要对其中的包装类进行拆箱)boolean x3 = flag ? objectBoolean.booleanValue() : simpleBoolean;
如果你清楚三目运算符的规则,那你就会正确地按照以上方式去定义 x1、x2 和 x3 的类型 。但是,并不是所有人都熟知这个规则,所以在实际应用中,还会出现以下几种定义方式:
boolean x4 = flag ? objectBoolean : objectBoolean;// 反编译后代码(三元表达式的结果要求是包装类,而 x4 是基本类型,所以编译器需要做拆箱)boolean x4 = (flag ? objectBoolean : objectBoolean).booleanValue();
Boolean x5 = flag ? simpleBoolean : simpleBoolean;// 反编译后代码(三元表达式的结果要求是基本类型,而 x5 是包装类型,所以编译器需要做装箱)Boolean x5 = Boolean.valueOf(flag ? simpleBoolean : simpleBoolean);
Boolean x6 = flag ? objectBoolean : simpleBoolean;// 反编译后代码(三元表达式的结果要求是基本类型,而 x5 是包装类型,所以编译器需要做装箱)Boolean x6 = Boolean.valueOf(flag ? objectBoolean.booleanValue() : simpleBoolean);
所以,日常开发中就有可能出现以上 6 种情况 。在以上 6 种情况中,如果是涉及到自动拆箱的,一旦包装类的值为 null,即 null.booleanValue(),就必然会发生 NPE(装箱不会,因为装箱是 Boolean.valueOf(null),这并不会抛 NPE) 。小伙伴们可以把以上的 x3、x4 以及 x6 中的的包装类设置成 null,看看是不是会抛 NPE:
boolean flag = true;boolean simpleBoolean = false;Boolean objectBoolean = Boolean.FALSE;// 将包装类设置为 nullBoolean nullBoolean = null;boolean x3 = flag ? nullBoolean : simpleBoolean;boolean x4 = flag ? nullBoolean : objectBoolean;Boolean x6 = flag ? nullBoolean : simpleBoolean;
以上三种情况,都会在执行时发生 NPE:- 其中 x3 和 x6 是三目运算符运算过程中,根据 JLS 的规则确定类型的过程中要做自动拆箱而导致的 NPE 。由于使用了三目运算符,并且第二、第三位操作数分别是基本类型和对象 。就需要对对象进行拆箱操作,由于该对象为 null,所以在拆箱过程中调用 null.booleanValue() 的时候就报了 NPE 。
- 而 x4 是因为三目运算符运算结束后根据规则他得到的是一个对象类型,但是在给变量赋值过程中进行自动拆箱所导致的 NPE 。
推荐阅读
- 作为程序员,我们不能只管上线,不管线上!
- 重大信号!会议定调下半年经济工作重点,关乎你买房买车找工作
- 梦见交通事故象征着什么
- word怎么在横线上打字 word怎么在横线上打字居中
- 三星堆重大考古发现与南派三叔 三星堆重大考古发现
- 体重大的人跑步技巧
- JaCoCo 助您毁灭线上僵尸代码
- 热烈祝贺千万职联APP线上发布会圆满结束!
- 40岁稳重大气的网名 2022年最酷的网名
- 成熟有魅力的男网名 有品位成熟的网名男网名稳重大气