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

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

前言

 

中国有句老话叫“事不过三”,指一个人犯了同样的错误,一次两次三次还可以原谅,超过三次就不可原谅了。有人指出这个“三”是虚数,用来泛指多次,所以“事不过三”不包括。至于“事不过三”包不包括“三”,可能跟每个人的底线有关系,属于哲学范畴,不在本文的讨论范围之内。

 

写代码也是如此,同一个代码“坑”,踩第一次叫“长了经验”,踩第二次叫“加深印象”,踩第三次叫“不长心眼”,踩三次以上就叫“可救药”。在本文中,笔者总结了一些Java坑,描述了问题现象,进行了问题分析,给出了避坑方法。希望大家在日常工作中,遇到了这类Java坑,能够提前避让开来。


一、 对象比较方法

 

JDK1.7提供的Objects.equals方法,非常方便地实现了对象的比较,有效地避免了繁琐的空指针检查。

 

1. 问题现象

 

在JDK1.7之前,在判断一个短整型、整型、长整型包装数据类型与常量是否相等时,我们一般这样写:

 

image.png 

 

从JDK1.7之后,提供了Objects.equals方法,并推荐使用函数式编程,更改代码如下:

 

image.png 

 

为什么直接把==替换为Objects.equals方法就会导致输出结果不一样?

 

2. 问题分析

 

通过反编译第一段代码,我们得到语句“System.out.println(shortValue == 12345);”的字节码指令如下:

 

image.png

 

原来,编译器会判断包装数据类型对应的基本数据类型,并采用这个基本数据类型的指令进行比较(比如上面字节码指令中的sipush和if_icmpne等),相当于编译器自动对常量进行了数据类型的强制转化。

 

为什么采用Objects.equals方法后,编译器不自动对常量进行数据类型的强制转化?通过反编译第二段代码,我们得到语句“System.out.println(Objects.equals(shortValue12345));”的字节码指令如下

 

image.png 

 

原来,编译器根据字面意思,认为常量12345默认基本数据类型是int,所以会自动转化为包装数据类型Integer。

 

在Java语言中,整数的默认数据类型是int,小数的默认数据类型是double。

 

通过分析Objects.equals方法的源代码可知:语句System.out.println(Objects.equals(shortValue12345)),因为Objects.equals的两个参数对象类型不一致,一个是包装数据类型Short,另一个是包装数据类型Integer,所以最终的比较结果必然是false;而语句“System.out.println(Objects.equals(intValue12345))”,因为Objects.equals的两个参数对象类型一致,都是包装数据类型Integer且取值相同,所以最终的比较结果必然是true。

 

3. 避坑方法

 

1) 保持良好的编码习惯,避免数据类型的自动转化

 

为了避免数据类型自动转化,更科学的写法是直接声明常量为对应的基本数据类型。

 

第一段代码可以这样写:

 

image.png 

 

第二段代码可以这样写:

 

image.png 

 

 

2) 借助开发工具或插件,及早地发现数据类型不匹配问题

 

在Eclipse的问题窗口中,我们会看到这样的提示:

 

image.png

 

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

 

“勿以善小而不为”,不要因为改动很小就不需要进行单元测试了,往往Bug都出现在自己过度自信的代码中。像这种问题,只要进行一次单元测试,是完全可以发现问题的。

 

注意

进行必要单元测试,适用于以下所有案例,所以下文不再累述。


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

相关文章
|
2月前
|
算法 Java
「译文」Java 垃圾收集参考手册(四):Serial GC
「译文」Java 垃圾收集参考手册(四):Serial GC
|
2月前
|
算法 Java PHP
「译文」Java 垃圾收集参考手册(一):垃圾收集简介
「译文」Java 垃圾收集参考手册(一):垃圾收集简介
|
2月前
|
网络协议 Java Maven
Java自救手册
Java自救手册
57 2
|
2月前
|
Java
电子书阅读分享《Java工程师成神之路》
电子书阅读分享《Java工程师成神之路》
52 1
|
1月前
|
消息中间件 Dubbo Java
互联网 Java 工程师1000道面试题(485页)
互联网 Java 工程师1000道面试题(485页)
28 0
|
1月前
|
人工智能 监控 Java
招个Java工程师,却发现了一个宝藏平台
招个Java工程师,却发现了一个宝藏平台
21 0
招个Java工程师,却发现了一个宝藏平台
|
2月前
|
SQL 存储 Java
[Java]细节、经验
[Java]细节、经验
45 0
[Java]细节、经验
|
2月前
|
算法 安全 Java
「译文」Java 垃圾收集参考手册(三):GC 算法基础篇
「译文」Java 垃圾收集参考手册(三):GC 算法基础篇
|
2月前
|
算法 Java
「译文」Java 垃圾收集参考手册(五):Parallel GC
「译文」Java 垃圾收集参考手册(五):Parallel GC
|
2月前
|
算法 Java
「译文」Java 垃圾收集参考手册(六):Concurrent Mark and Sweep
「译文」Java 垃圾收集参考手册(六):Concurrent Mark and Sweep