关于Java 中Integer 和Long对象 对比的陷阱(简单却容易犯的错误)
彩票客户端“忘记密码”功能有bug,今天调试时,发现了原因:
功能模块中有一段:
if(userpo.getId()!=Long.valueOf(uid)){
throw new VerifyException("mobile have been binded for uid=" + uid ,
AppCode.VERIFY_MOBILE_IS_BIND);
}
问题就处在两个Long型对象的比较。
情景:
userpo.getId()返回一个Long型对象,值是10027;
Long.valueOf(uid)返回一个Long型对象,值也是10027;
但是他们 != 运算的值是 true ,在java中对象对比一般都使用 equals 方法或者compareTo方法
解决方案:
以上代码应该改成:userpo.getId().equals(Long.valueOf(uid)) 返回 true
猜想:
当初代码肯定是通过测试的,那当初是为什么会通过测试?因为最初数据小。
思考:
值得注意的是,最初学java时,我印象中Integer和Long类型的对象有使用过 == 、!= 这样来比较,结果好像也对过。
其实确实有一种情况使用 == 、!= 这样来比较也对。
例如我写了一个测试类测试Integer和Long类型对象的比较:
public class Test {
public static void main(String[] args) {
Integer a = new Integer(10);
Integer b = new Integer(10);
System.out.println("a==b:" + (a==b)); //很明显false
Integer c = 129;
Integer d = 129;
System.out.println("c==d:" + (c==d)); //false
Integer e = 127;
Integer f = 127;
System.out.println("e==f:" + (e==f));//true
Long h = 128L;
Long g = 128L;
System.out.println("h==g:" + (h==g));//false
System.out.println("h.equals(g):" + h.equals(g));//true
System.out.println("h.compareTo(g):" + h.compareTo(g));// 0
Long k = 127L;
Long m = 127L;
System.out.println("k==m:" + (k==m));//true
System.out.println("k.equals(m):" + k.equals(m));//true
System.out.println("k.compareTo(m):" + k.compareTo(m));//0
}
}
执行结果:
a==b:false
c==d:false
e==f:true
h==g:false
h.equals(g):true
h.compareTo(g):0
k==m:true
k.equals(m):true
k.compareTo(m):0
原因:查看Integer源代码后发现Integer有个内部类IntegerCache,它维护了一个Integer数组cache[] ,长度为256,还有一个静态块
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
很明显这个静态块已经默认认创建出了-128~127 的 Integer 数据,因此Integer在创建对象时,若值在(-128到127)范围内,则直接从缓冲区中取,若超过该范围则创建新对象,因此在-128到127范围内Integer对象值相同时,对象 ==返回true
Long对象同理。
注:内容结合了网络的一些解答。
关于Java 中Integer 和Long对象 对比的陷阱(简单却容易犯的错误)的更多相关文章
- 转!! Java中如何遍历Map对象的4种方法
在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都 ...
- java中基本类型封装对象所占内存的大小(转)
这是一个程序,java中没有现成的sizeof的实现,原因主要是java中的基本数据类型的大小都是固定的,所以看上去没有必要用sizeof这个关键字. 实现的想法是这样的:java.lang.Runt ...
- 【转】Java中如何遍历Map对象的4种方法
原文网址:http://blog.csdn.net/tjcyjd/article/details/11111401 在Java中如何遍历Map对象 How to Iterate Over a Map ...
- (转)在Java中如何遍历Map对象
在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都 ...
- 深入理解Java中的不可变对象
深入理解Java中的不可变对象 不可变对象想必大部分朋友都不陌生,大家在平时写代码的过程中100%会使用到不可变对象,比如最常见的String对象.包装器对象等,那么到底为何Java语言要这么设计,真 ...
- (转载)Java中如何遍历Map对象的4种方法
在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都 ...
- java中Integer比较需要注意的问题
java中Integer比较需要注意的问题 package com.srie.test; import java.util.HashMap; import java.util.Map; public ...
- 【JAVA零基础入门系列】Day11 Java中的类和对象
今天要说的是Java中两个非常重要的概念--类和对象. 什么是类,什么又是对象呢?类是对特定集合的概括描述,比如,人,这个类,外观特征上,有名字,有年龄,能说话,能吃饭等等,这是我们作为人类的相同特征 ...
- java中Integer 和String 之间的转换
java中Integer 和String 之间的转换 将数组转换成字符串:char[] array = {'a','b','c','d','e'};String str = new String(ar ...
随机推荐
- 使用LinkedList模拟栈数据结构的集合
封装MyStack类 public class MyStack { private LinkedList link; //调用MyStack创建对象的时候其实是调用的LinkedList创建的是Lin ...
- Git+Jenkins+FileGee 发布php应用
Git:做版本控制,回滚版本(coding.net) Jenkins:代码下载,提供webhook url FileGee:同步代码(一个国产同步.备份软件非常强大,而且便宜企业版只要498) jen ...
- js 俄罗斯方块源码,简单易懂
1.自己引入jquery <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...
- 排序-----插入排序(python版)
直接插入排序的算法思路: (1) 设置监视哨r[0],将待插入纪录的值赋值给r[0]: (2) 设置开始查找的位置j: (3) 在数组中进行搜索,搜索中将第j个纪录后移,直至r[0].key≥r[j] ...
- JavaScript实现功能全集
JavaScript就这么回事1:基础知识 1 创建脚本块 <script language="JavaScript">JavaScript code goes her ...
- python+Django框架运用(一)
Django 介绍: django是一个采用Python语言开发的开源框架,2005年发布.早期是做新闻以及内容管理的网站的,提供了非常强大的后管理系统. django官网:https://www.d ...
- python 用正则表达式把”0102030405”分成5组('0', '1'), ('0', '2'), ('0', '3'), ('0', '4'), ('0', '5')
把”0102030405”分成5组('0', '1'), ('0', '2'), ('0', '3'), ('0', '4'), ('0', '5') re.findall(r"(\d)(\ ...
- 人工智能范畴及深度学习主流框架,谷歌 TensorFlow,IBM Watson认知计算领域IntelligentBehavior介绍
人工智能范畴及深度学习主流框架,谷歌 TensorFlow,IBM Watson认知计算领域IntelligentBehavior介绍 ================================ ...
- new Runnable中的 this
package com.test; public class BB extends AA{ public String bb = "bbbbb"; public void gg() ...
- Ubuntu系统下Jenkins的本地构建基本方法
上一篇文章介绍了,jenkins的安装和系统配置之后,配置登录成功后,就可以新建jenkins构建项目,用于自动化构建. 1.项目名称和项目描述 点击左上角的 新建任务,输入项目名称,选择 构建一个自 ...