由一次代码调试引发的对JAVA数值包装类型的使用的思考

简介: 由一次代码调试引发的对JAVA数值包装类型的使用的思考

问题的背景是这样的,判断数据库表中的一列是否有值以及该值是否是0,该列是数值型的,JAVA类中的类型是Long,注意这里使用的包装类。实际业务中的代码实现如下:

if(list!=null&&list.size()>0){
for(PoObjectobj:list){
if(obj.getFlowId()!=null&&!obj.getFlowId().equals(0)){
obj.setUrl(url.replace("aaa",String.valueOf(obj.getFlowId())));
        }
    }
}

从数据库表中查询出数据列表,然后遍历,判断是否flowId不为空且不为0的时候,对url属性做一个replace。url属性是显示到前端做跳转使用的。数据库表里flowId对应的列值都是0,启动项目的时候,发现页面上url地址都有值,这样就都做了跳转。本意是为0了,前端的url属性就是空的,提示暂无链接。那么问题出现在哪里了呢,就是!obj.getFlowId().equals(0)这个判断,这个判断对于flowId为0的时候返回是正确的,这就奇怪了,为啥0!=0是对的呢?其实是错用了equals方法。正确的写法应该是

!obj.getFlowId().equals(0L)。JDK中对于Long的equals的实现如下:

/*** Compares this object to the specified object.  The result is* {@code true} if and only if the argument is not* {@code null} and is a {@code Long} object that* contains the same {@code long} value as this object.** @param   obj   the object to compare with.* @return  {@code true} if the objects are the same;*          {@code false} otherwise.*/publicbooleanequals(Objectobj) {
if (objinstanceofLong) {
returnvalue== ((Long)obj).longValue();
        }
returnfalse;
    }

0不是属于Long的,而0L是属于Long的,同样要注意的是Float的类型,0f和0的类型在Float的equals中也不是一样的概念。除了!obj.getFlowId().equals(0L)可以以外,还可以使用obj.getFlowId().compareTo(0L)==0去判断。这里面有个要注意的点就是Long的compareTo方法参数是Long类型的,所以如果你写compareTo(0)会报编译错误,强制你使用0L,而equeals方法的参数是Object类型的,所以不会报编译错误。由这点可以看出来编译器暴露出问题来的重要性了。可以用如下的测试用例测试一下几个包装类的比较:

publicstaticvoidmain(String [] args) {
Longid=0L;
Floata=0f;
longid2=0;
System.out.println(id2==0); //trueSystem.out.println(a.equals(0)); //falseSystem.out.println(a.equals(0f)); //trueSystem.out.println(id.equals(0)); //falseSystem.out.println(id.equals(0L)); //trueSystem.out.println(id.compareTo(0L)); //0    }

虽然是个小问题,但是刚入行的同学找了半天没找出来,还感觉很奇怪。也不是什么大问题,更不要怀疑JDK会出bugs或者会给你模棱两可的答案,从自己提供的参数去考虑,以及使用的方法执行的逻辑输出的结果是否是预期的结果这方面的入手。看看源码确实是个不错的成长途径。可能以后会遇到Integer的比较的时候会存在小于还是大于127的缓存的问题,希望能避坑。

目录
相关文章
|
16天前
|
存储 Java Windows
java基础(9)数据类型中的char类型以及涉及到的转义字符
Java中的char类型可以存储一个中文字符,因为它占用两个字节。转义字符允许在代码中使用特殊字符,例如`\n`表示换行,`\t`表示制表符,`\\`表示反斜杠,`\'`表示单引号,`\"`表示双引号。可以使用`\u`后跟Unicode编码来表示特定的字符。
30 2
java基础(9)数据类型中的char类型以及涉及到的转义字符
|
8天前
|
存储 安全 Java
Java 数据结构类型总结
在 Java 中,常用的数据结构包括基础数据结构(如数组和字符串)、集合框架(如 Set、List 和 Map 接口的多种实现)、特殊数据结构(如栈、队列和双端队列)、链表(单链表、双链表和循环链表)以及图和树等。这些数据结构各有特点和适用场景,选择时需考虑性能、内存和操作需求。集合框架提供了丰富的接口和类,便于处理对象集合。
|
16天前
|
Java
java基础(10)数据类型中的整数类型
Java中的整数类型包括byte、short、int和long。整数字面值默认为int类型,加L表示long类型。整数字面值可以是十进制、八进制(0开头)或十六进制(0x开头)。小容量类型(如int)可自动转换为大容量类型(如long),但大容量转小容量需强制转换,可能导致精度损失。
27 2
|
19天前
|
监控 算法 Java
深入理解Java中的垃圾回收机制在Java编程中,垃圾回收(Garbage Collection, GC)是一个核心概念,它自动管理内存,帮助开发者避免内存泄漏和溢出问题。本文将探讨Java中的垃圾回收机制,包括其基本原理、不同类型的垃圾收集器以及如何调优垃圾回收性能。通过深入浅出的方式,让读者对Java的垃圾回收有一个全面的认识。
本文详细介绍了Java中的垃圾回收机制,从基本原理到不同类型垃圾收集器的工作原理,再到实际调优策略。通过通俗易懂的语言和条理清晰的解释,帮助读者更好地理解和应用Java的垃圾回收技术,从而编写出更高效、稳定的Java应用程序。
|
2月前
|
Java
【Java基础面试五】、 int类型的数据范围是多少?
这篇文章回答了Java中`int`类型数据的范围是-2^31到2^31-1,并提供了其他基本数据类型的内存占用和数值范围信息。
【Java基础面试五】、 int类型的数据范围是多少?
|
1月前
|
自然语言处理 算法 Java
Java如何判断两句话的相似度类型MySQL的match
【9月更文挑战第1天】Java如何判断两句话的相似度类型MySQL的match
21 2
|
2月前
|
Java 应用服务中间件 HSF
Java应用结构规范问题之dal层中的mapper数据源类型进行组织的问题如何解决
Java应用结构规范问题之dal层中的mapper数据源类型进行组织的问题如何解决
|
2月前
|
前端开发 Java 数据库
Java系列之 Long类型返回前端精度丢失
这篇文章讨论了Java后端实体类中Long类型数据在传递给前端时出现的精度丢失问题,并提供了通过在实体类字段上添加`@JsonSerialize(using = ToStringSerializer.class)`注解来确保精度的解决方法。
|
2月前
|
开发工具 数据安全/隐私保护
【Azure Developer】使用MSAL4J 与 ADAL4J 的SDK时候,遇见了类型冲突问题 "java.util.Collections$SingletonList cannot be cast to java.lang.String"
【Azure Developer】使用MSAL4J 与 ADAL4J 的SDK时候,遇见了类型冲突问题 "java.util.Collections$SingletonList cannot be cast to java.lang.String"
|
2月前
|
Java
成功解决:java: 找不到符号 符号: 方法 getSort() 位置: 类型为com.atguigu.gulimall.product.entity.CategoryEntity的变量 menu1
这篇文章讨论了Java中遇到的一个常见错误:"java: 找不到符号 符号: 方法 getSort() 位置: 类型为com.atguigu.gulimall.product.entity.CategoryEntity的变量 menu1",即在尝试调用一个不存在的方法时出现的问题,并提供了相应的解决方法。