《Java工程师必读手册》——Java经验之谈系列——那些年,我们踩过的那些Java坑(2)

简介: 《Java工程师必读手册》——Java经验之谈系列——那些年,我们踩过的那些Java坑(2)

接上篇:https://developer.aliyun.com/article/1228290?groupCode=java


二、 三元表达式拆包

 

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

 

1. 问题现象

 

image.png

 

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

 

 

2. 问题分析

 

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

 

image.png 

 

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

 

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

 

若两个表达式类型相同,返回值类型为该类型;

若两个表达式类型不同,但类型不可转换,返回值类型为Object类型;

若两个表达式类型不同,但类型可以转化,先把包装数据类型转化为基本数据类型,然后按照基本数据类型的转换规则(byte

 

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

 

3. 避坑方法

 

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

 

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

 

image.png 

 

2) 尽量使用基本数据类型,避免包装数据类型的拆装包

 

如果在三元表达式中有算术计算,尽量使用基本数据类型,避免包装数据类型的拆装包。改写代码如下:

 

image.png


接下篇:https://developer.aliyun.com/article/1228288?spm=a2c6h.13148508.setting.21.7be64f0ebemzoR

相关文章
|
3月前
|
算法 Java
「译文」Java 垃圾收集参考手册(四):Serial GC
「译文」Java 垃圾收集参考手册(四):Serial GC
|
3月前
|
算法 Java PHP
「译文」Java 垃圾收集参考手册(一):垃圾收集简介
「译文」Java 垃圾收集参考手册(一):垃圾收集简介
|
3月前
|
网络协议 Java Maven
Java自救手册
Java自救手册
58 2
|
1月前
|
人工智能 Kubernetes Java
Java开发工程师如何紧跟技术前沿对于保持专业竞争力、提升工作效率以及适应行业发展?
【4月更文挑战第4天】Java开发工程师如何紧跟技术前沿对于保持专业竞争力、提升工作效率以及适应行业发展?
25 4
|
2月前
|
消息中间件 Dubbo Java
互联网 Java 工程师1000道面试题(485页)
互联网 Java 工程师1000道面试题(485页)
31 0
|
2月前
|
人工智能 监控 Java
招个Java工程师,却发现了一个宝藏平台
招个Java工程师,却发现了一个宝藏平台
24 0
招个Java工程师,却发现了一个宝藏平台
|
3月前
|
SQL 存储 Java
[Java]细节、经验
[Java]细节、经验
46 0
[Java]细节、经验
|
3月前
|
算法 安全 Java
「译文」Java 垃圾收集参考手册(三):GC 算法基础篇
「译文」Java 垃圾收集参考手册(三):GC 算法基础篇
|
3月前
|
算法 Java
「译文」Java 垃圾收集参考手册(五):Parallel GC
「译文」Java 垃圾收集参考手册(五):Parallel GC
|
3月前
|
算法 Java
「译文」Java 垃圾收集参考手册(六):Concurrent Mark and Sweep
「译文」Java 垃圾收集参考手册(六):Concurrent Mark and Sweep