《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开发工程师的职业规划应该是什么样的?
Java开发工程师的职业规划涵盖多个阶段,包括初入行业(0-1年)、技能提升(1-3年)、技术专家(3-5年)及管理或专家路线选择(5年以上)。各阶段设定了明确的技能要求与职业目标,从掌握Java基础、常用框架到深入研究高级技术、微服务架构乃至担任管理职务或成为技术专家。通过持续学习与实践,结合个人兴趣,Java工程师可在技术或管理领域找到合适的发展方向,最终实现职业成功。
428 83
|
2月前
|
设计模式 架构师 Java
Java开发工程师转架构师需要学习什么
Java开发工程师转型为架构师需掌握多项技能:精通Java及框架、数据库与分布式系统;熟悉设计模式与架构模式;积累项目经验;提升沟通与领导力;持续学习新技术;培养系统设计与抽象能力;了解中间件及开发工具;并注重个人特质与职业发展。具体路径应结合个人目标与实际情况制定。
68 18
|
2月前
|
人工智能 前端开发 Java
Java开发工程师转哪个行业比较好?
Java开发工程师转哪个行业比较好?
303 2
|
3月前
|
人工智能 自然语言处理 Java
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
文章介绍了Spring AI,这是Spring团队开发的新组件,旨在为Java开发者提供易于集成的人工智能API,包括机器学习、自然语言处理和图像识别等功能,并通过实际代码示例展示了如何快速集成和使用这些AI技术。
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
|
2月前
|
小程序 前端开发 JavaScript
Java开发工程师转小程序开发的前景如何?
Java开发工程师转小程序开发的前景如何?
51 0
|
5月前
|
Java 开发者
【技术成长日记】Java 线程的自我修养:从新手到大师的生命周期修炼手册!
【6月更文挑战第19天】Java线程之旅,从新手到大师的进阶之路:始于创建线程的懵懂,理解就绪与运行状态的成长,克服同步难题的进阶,至洞悉生命周期的精通。通过实例,展示线程的创建、运行与同步,展现技能的不断提升与升华。
39 2
|
4月前
|
Java
图解java工程师学习路线
图解java工程师学习路线
244 0
|
5月前
|
Java 数据安全/隐私保护
Java基础手册二(类和对象 对象创建和使用 面向对象封装性 构造方法与参数传递 this关键字 static关键字 继承 多态 方法覆盖 final关键字 访问控制权限修饰符)
Java基础手册二(类和对象 对象创建和使用 面向对象封装性 构造方法与参数传递 this关键字 static关键字 继承 多态 方法覆盖 final关键字 访问控制权限修饰符)
35 0
|
5月前
|
存储 Java
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
Java基础手册(标识符 关键字 字面值 变量 数据类型 字符编码 运算符 控制语句 方法及方法重载和递归 面向对象与面向过程)
39 0
|
5月前
|
存储 Java 编译器
技术经验解读:一文带你搞懂java中的变量的定义是什么意思
技术经验解读:一文带你搞懂java中的变量的定义是什么意思
45 0
下一篇
无影云桌面