三元表达式拆包

三元表达式是Java编码中的一个固定语法格式:“条件表达式?表达式1:表达式2”。三元表达式的逻辑为:“如果条件表达式成立,则执行表达式1,否则执行表达式2”。

1.问题现象

boolean condition = false;
Double value1 = 1.0D;
Double value2 = 2.0D;
Double value3 = null;
Double result = condition ? value1 * value2 : value3;//抛出空指针异常

当条件表达式condition等于false时,直接把Double对象value3赋值给Double对象result,按道理没有问题呀,为什么会抛出空指针异常(NullPointerException)?

2.问题分析

通过反编译代码,我们得到语句"Double result = condition ? value1 * value2 : value3;"的字节码指令如下:

17  iload_1 [condition]
18  ifeq 33
21  aload_2 [value1]
22  invokevirtual java.lang.Double.doubleValue() : double [24]
25  aload_3 [value2]
26  invokevirtual java.lang.Double.doubleValue() : double [24]
29  dmul
30  goto 38
33  aload 4 [value3]
35  invokevirtual java.lang.Double.doubleValue() : double [24]
38  invokestatic java.lang.Double.valueOf(double) : java.lang.Double [16]
41  astore 5 [result]
43  getstatic java.lang.System.out : java.io.PrintStream [28]
46  aload 5 [result]

在第33行,加载Double对象value3到操作数栈中;在第35行,调用Double对象value3的doubleValue方法。这个时候,由于value3是空对象null,调用doubleValue方法必然抛出抛出空指针异常。但是,为什么要把空对象value3转化为基础数据类型double?

查阅相关资料,得到三元表达式的类型转化规则:

  1. 若两个表达式类型相同,返回值类型为该类型;
  2. 若两个表达式类型不同,但类型不可转换,返回值类型为Object类型;
  3. 若两个表达式类型不同,但类型可以转化,先把包装数据类型转化为基本数据类型,然后按照基本数据类型的转换规则(byte

根据规则分析,表达式1(value1 * value2)计算后返回基础数据类型double,表达式2(value3)返回包装数据类型Double,根据三元表达式的类型转化规则判断,最终的返回类型为基础数据类型double。所以,当条件表达式condition等于false时,需要把空对象value3转化为基础数据类型double,于是就调用了value3的doubleValue方法抛出了空指针异常。

可以用以下案例验证三元表达式的类型转化规则:

boolean condition = false;
Double value1 = 1.0D;
Double value2 = 2.0D;
Double value3 = null;
Integer value4 = null;
// 返回类型为Double,不抛出空指针异常
Double result1 = condition ? value1 : value3;
// 返回类型为double,会抛出空指针异常
Double result2 = condition ? value1 : value4;
// 返回类型为double,不抛出空指针异常
Double result3 = !condition ? value1 * value2 : value3;
// 返回类型为double,会抛出空指针异常
Double result4 = condition ? value1 * value2 : value3;

3.避坑方法

(1)尽量避免使用三元表达式,可以采用if-else语句代替

如果三元表达式中有算术计算和包装数据类型,可以考虑利用if-else语句代替。改写代码如下:

boolean condition = false;
Double value1 = 1.0D;
Double value2 = 2.0D;
Double value3 = null;
Double result;
if (condition) {result = value1 * value2;
} else {result = value3;
}

(2)尽量使用基本数据类型,避免数据类型的自动转化

如果三元表达式中有算术计算和包装数据类型,可以考虑利用if-else语句代替。改写代码如下:

boolean condition = false;
double value1 = 1.0D;
double value2 = 2.0D;
double value3 = 3.0D;
double result = condition ? value1 * value2 : value3;

(3)进行覆盖性单元测试,尽量把问题发现在研发阶段

像这种问题,只要编写一些单元测试用例,进行一些覆盖性测试,是完全可以提前发现的。

Java三元表达式拆包相关推荐

  1. 三元表达式java_记录一个Java三元表达式中的陷阱

    今天遇到一个奇怪的Java三元表达式中的空指针异常.特此记录. 代码 代码示意如下: Integer itemVO = null; Integer globleLatenessToleranceUse ...

  2. Java三元表达式学习笔记

    活不多说,直接上代码 ----------------------------------------以下代码仅为个人学习理解,简单明了,仅供参考--------------------------- ...

  3. JAVA三元表达式详解

    三元表达式即 boolean?true:false 这是表达式是语法 例句一个demo: int new1=10; int new2=20; int new3=null; new3 = new2> ...

  4. java 三元表达式

    eg1: static int demo01 (int a , int b ){int c = a > b ? 0 :1;return c; } public static void main( ...

  5. java三元表达式因自动拆箱导致的NPE问题

    开发中发生的奇怪的问题,类似如下的代码NPE了... boolean flag = false; Integer a = null; Integer n = flag ? 1 : a; 原来是在计算三 ...

  6. java三元表达式的解读

    如下: 其中isLastSeparator是boolean型 str.indexOf(ch)表示ch第一次出现的索引,lastIndexOf(ch)表示ch最后一次出现的索引. 三元表达式的运算顺序: ...

  7. java三元表达式必须返回_java – 三元运算符的右手表达式必须兼容...

    您的方法声明返回类型是String.任何return语句都必须生成一个与声明的返回类型兼容的表达式. 但是,在这种情况下,返回类型可以是int,这解释了编译器拒绝它的原因. 这不是特定于三元运算符的, ...

  8. java三元表达式嵌套_三元运算符的嵌套详解:分别在JSTL、JavaScript和Java中

    用来完成简单的选择逻辑,即根据条件判断,从两个选择中选择一种执行. 使用格式: (条件表达式)?表达式1:表达式2: 运算规则:条件表达式  值为一个布尔值,当值为true的时候 执行表达式1   否 ...

  9. java 三元表达式_Java探究心得之三元运算符

    首先看一下三元运算符的格式 [条件语句] ? [表达式1] : [表达式2] 其中如条件语句为真执行表达式1,否则执行表达式2.简单的例子就不举了,来点其它的.在JDK1.5以前的版本中,表达式1和表 ...

最新文章

  1. GUI_DOWNLOAD加列名行
  2. 冷静对待你遇到的所有Java内存异常
  3. 北京创客空间_世界上最大的创客空间,可增强开放安全性等
  4. php结束外部程序,PHP执行外部程序的方法
  5. 关系抽取之远程监督算法:别再跟我提知识图谱(下篇)
  6. 用java实现学生成绩管理系统_学生成绩管理系统(java实现)
  7. 一键修改QQ运动刷步助手 V3.0
  8. 由WPS 2005想到的
  9. Xshell实现命令快速输入
  10. 大厂的区块链之路|蚂蚁金服怎么玩?
  11. docker ps3netsrv_QNAP 威联通 NAS TS-212P应用系列 篇一:实践基于QNAP平台搭建PS3NETSRV服务...
  12. SqlServer使用top 100 PERCENT 无法排序的问题
  13. phalcon mysql in_phalcon:跟踪sql语句
  14. 众海世纪影业:五一档19部影片“扎堆”,能否再次掀起观影热潮?
  15. webstorm配置环境变量_Webstorm 配置与使用 Less
  16. web页面之响应式布局
  17. 串口屏应用案例_大彩串口屏在高拍仪上的应用方案
  18. android设计模式应用--中介者模式
  19. 高职计算机应用专业的课程有哪些,高职计算机应用专业课程优化与整合
  20. 高考之后,入世之前,我上了数据的“贼船”

热门文章

  1. Python构造函数takes no arguments
  2. CTF----Web真零基础入门
  3. Code for Rerun DropDownButtonFactory
  4. Java 实现递归算法(项目中的简单例子)
  5. element el-input 去除边框/自定义
  6. Android翻页入门
  7. 酒吧攻略:一文解读酒吧类型
  8. 41、用户sa登录失败,错误18456
  9. 精彩回顾 | Fortinet Accelerate 2023·中国区巡展杭州站
  10. JavaScript实现点击文字验证