Java 包装类型 == 操作引发的 Bug

背景

一个简单的列表检索功能,列表元素有一个 Long 类型的属性,遍历过程中犯了一个低级错误,导致功能流程始终错误,本文将分享两个低级错误引发的 bug。

两个 Long 类型的 ==

查找某个元素 A 在列表 B 中对应的对象的时候,根据元素主键查询,主键类型为包装类型 Long ,遍历流程如下:

复制代码
for(MyData temp:b){
     if (temp.getId() == a.getId() { //  MyData 的 id 属性为 Long 类型
          return temp;
     }
}

这么一段简单的查找代码,结果怎么都找不到目标对象,断点调试发现问题出在 == 操作上,改成 equals 就可以了。

关于 Java Long 的包装类型和元素类型的判断相等的操作回顾:

复制代码
Long a = 81487354807713792L;
Long b = 81487354807713792L;
System.out.println(a==b); // false
System.out.println(a.equals(b)); // true

long c = 81487354807713792L;
long d = 81487354807713792L;
System.out.println(c==d); // true

对 Collections.EMPTY_SET 进行 add 引发的异常

另一个低级错误是对 Collections.EMPTY_SET 进行 add 引发的,需要合并两个集合,第一个集合 A 可能是 Collections.EMPTY_SET ,最终将另一个集合 B 合并到 A 得到一个大集合。

复制代码
Set<MyData> a = getDatas();// 如果为空,返回了 Collections.EMPTY_SET
Set<MyData> b = getDatas1();
a.addAll(b);

当集合 a 为集合的空对象时,操作异常:

复制代码
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractCollection.add(AbstractCollection.java:262)

修正方式 :如果需要直接对一个集合进行 add ,就不能用 Collections.EMPTY_SET。

Collections 的空集合使用注意事项

以 Collections.EMPTY_SET 为例,跟源码它的定义主要是下面三行代码:

复制代码
public static final Set EMPTY_SET = new EmptySet<>();

private static class EmptySet<E> extends AbstractSet<E>

AbstractSet<E> extends AbstractCollection

核心在于 AbstractCollection 类的 add,默认直接抛出了异常,限制了空集合不允许添加:

复制代码
public boolean add(E e) {
     throw new UnsupportedOperationException();
 }

结论 :java.util.Collections 类中所有的 EMPTY_XXX 对象都不能进行 add 操作。

启示录

定位到这两个低级错误后,想起那句调侃:代码编写分分钟,bug 查找两小时。这两个问题恰好是一个比较复杂的流程的一部分,构建环境进行测试,测一次差不多十几分钟,加上机器怠工,跟这俩小问题,耗了两个小时。

以此文为记,这么深刻的过程,估计以后也不会再犯了!

相关推荐
秋饼15 分钟前
LLM API密钥动态轮换实战:Spring Vault + Spring AI + 多Provider路由
java·ai·技术分享·后端开发
gCode Teacher 格码致知24 分钟前
Pandas教学-17:Series与Dataframe的关系
开发语言·python·pandas
发量惊人的中年网工28 分钟前
分公司访问总部ERP慢怎么办?SD-WAN组网的排查与验收要点
服务器·开发语言·php
下页、再停留1 小时前
【C#桌面客户端系列学习-15】生成可视化图表之折线图、柱状图、饼状图
开发语言·c#
ShineWinsu1 小时前
对于JavaScript:操作元素的解析
开发语言·前端·javascript·面试·web·dom·元素
福兮说2 小时前
JSON 格式正确,数据就可靠吗?我用一份自编配置检查类型与空值
java·前端·json
益莱储中国2 小时前
深度解析:RF 实验室从 5G迈向 6G 的过程中保持技术领先与设备升级的路径
开发语言·php
紧跟先前的步伐3 小时前
Go AI Agent 实战 03|Token、上下文窗口与模型调用成本
java·人工智能·golang
benchmark_cc3 小时前
Python 量化系统如何设计统一的数据访问接口:从策略解耦到数据层架构
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
const_qiu4 小时前
第四章 00:开篇 —— 从「会聊天」到「记得住、会干活、能协作」
java·开发语言·人工智能·python