bug?

前几天有位朋友找我,说:“老哥,老哥,我好像发现了Integer一个bug,你帮我看看什么情况?”,说完给了我两个很简单的demo,上代码。


100 == 100

1000 == 1000

通过代码,我们可以看到,这是很简单的“100100”、“10001000”,但是为什么一个是“true”,一个是“false”,难道真的是bug?

使用Integer的场景

我们平时用Integer,都是用来操作整型数值相关操作,比如Model里面的自增主键id,类型标识type等等。

比如我们有个类型,性别,1 男 2 女;那么我们展示到页面的代码一般会这么写:

public static final Integer MAN = 1;

public static final Integer WOMAN = 1;

... ...

if(MAN == user.getSex()) {

return "男";

} else if(WOMAN == user.getSex()) {

return "女";

}

很常见,基本也没遇到过问题,因为我们也很少类型超过几百上千的,只有特殊场景的设计才有。

Integer是什么,怎么正确比较

我们先看看Integer的定义,打开Integer的源代码文件:

class Ineger

通过截图中的代码,我们可以看到,Integer是class,所以Integer是对象。

我们都知道对象的“==”比较,是比较的两引用对象的指针(内存地址)是否相等,也就是是否指向同一对象。既然是对象,那么Integer的正确比较姿势,肯定是“equals”了,即“a.equals(b)”。

我们再回头看前面的例子,“a”和“b”并不是同一个对象。那为什么“100”可以,“1000”就不可以?

自动装箱拆箱

装箱,是自动将基本数据类型转换为包装器类型;

拆箱,是自动将包装器类型转换为基本数据类型;

在这里我们不对“装箱拆箱”做太多的解释,后续我们再开专题讨论。

回到Integer,简单了解下其装箱拆箱分别做了什么操作。

Integer类型的赋值给int类型,调用intValue()方法进行拆箱赋值;

int类型赋值给Integer,会调用valueOf()方法对int进行装箱赋值。

看下相应的源码:

intValue()

valueOf()
我们可以看到,除了“return new Integer(i)”,还有一段if判断,大致意思我们可以看出来,当在“IntegerCache.low”与“IntegerCache.high”区间的时候,会返回“IntegerCache.cache[]”的一个值。

好了,到此,我们可以看到,当装箱 Integer 的值在一定区间的时候,并不是“new”出来的,而是从 IntegerCache.cache[] 中取出来的。所以我们再看看 IntegerCache 是如何定义的。

Integer 缓冲池 IntegerCache

话不多说,先上源码:

IntegerCache

由于时间有限,我们就看看重点,

for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);

这两行代码,就是初始化了cache[]数组的值,每个值都是对应的数值的Integer对象。

1000 不等于 1000 还是bug吗?

到此,我们已经得知,几个重点:

  1. Integer 是对象
  2. Integer 值比较应该使用 equals()
  3. Integer 有个缓存池 IntegerCache,预初始化 -127 至 127 的 Integer 对象\

再看看demo,使用的是“==”并不是“equals()”,所以这并不是bug,而是比较的方式不对,正确的比较姿势是“equals()”,我们来实践一下看看。

举一反三

同样是装箱拆箱,Long是否也有缓存池呢?Double呢?

My Blog

blog.guijianpan.com

技术交流

听说Integer有bug?1000不等于1000?的更多相关文章

  1. 糟糕,你写的 BUG 要被存1000年了!

    摘要:代码冰封,祖传千年! 把大象放在冰箱需要几步? 三步!把代码放在北极需要几步?纳尼? GitHub刚刚公布了一组照片,你写的代码(BUG)上周已经被打包运往北极保存. 只要你2月2日以前贡献过的 ...

  2. hide(1000)跟show(1000)

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. NGUI panel 之下widget最大depth是1000,超过1000时OnClick会出问题!

    经过我的测试发现ngui widget的depth是有限制的!原本以为只要不同panel间的depth设置好了后无论widget depth如何设置都没问题,直到我们项目中出现奇怪的点击问题后才发现这 ...

  4. Java Integer于Int 进行==双等于的内存比较时的一些问题说明

    转自: https://blog.csdn.net/xingkongdeasi/article/details/79618421 部分有所修改: 前言: 越是简单的东西,我们往往越是没有去把它明白,但 ...

  5. java 中 sleep(1000) 和 wait(1000) 的区别?

    1.首先 sleep 方法是Thread类中的静态方法,他的作用是使当前线程暂时睡眠指定的时间,可以不用放在synchronized方法或者代码块中,但是 wait 方法是Object类的方法,它是使 ...

  6. 验证HashSet和HashMap不是线程安全

    JAVA集合类: java.util包下的HashSet和HashMap类不是线程安全的, java.util.concurrent包下的ConcurrentHashMap类是线程安全的. 写2个测试 ...

  7. Java基础教程——包装类

    Java出道之时,自诩为"纯面向对象的语言",意思是之前的所谓"面向对象语言"不纯. 但是,有人指责Java也不纯--8种基本类型并非类类型.为此,Java为他 ...

  8. C++ 类类型转换函数explicit 关键字

    标准数据之间会进行  隐式类型安全转换. 转换规则: 隐式类型转换的问题: #include <iostream> #include <string> using namesp ...

  9. 计算机中K到底是1000还是1024?

    1000和1024的争论,其实是传输领域和存储领域概念不清引起的;在传输领域,1秒钟传输多少字位(即b,bit),肯定是用10进制表示,所以是1kb=1000b,即1秒钟传输1000个比特位;就好像: ...

随机推荐

  1. Water 2.5.6 发布,一站式服务治理平台

    Water(水孕育万物...) Water 为项目开发.服务治理,提供一站式解决方案(可以理解为微服务架构支持套件).基于 Solon 框架开发,并支持完整的 Solon Cloud 规范:已在生产环 ...

  2. 如何使用 Spring Boot 实现异常处理?

    Spring 提供了一种使用 ControllerAdvice 处理异常的非常有用的方法. 我们通过实现一个 ControlerAdvice 类,来处理控制器类抛出的所有异常.

  3. ubuntu16 和ubuntu18安装及设置静态ip

    1.准备ubuntu16镜像2.安装:https://zhuanlan.zhihu.com/p/1447048653.安装ubuntu后,sudo passwd root这个命令建立root用户的密码 ...

  4. 202A 202B 202C 202D 202E字符的作用及解释

    这里你会发现在值的前后有2个\u开头的控制字符:转换网址:http://www.jsons.cn/utf8/ 解释:https://blog.csdn.net/haiyan1111/article/d ...

  5. 什么是通知(Advice)?

    特定 JoinPoint 处的 Aspect 所采取的动作称为 Advice.Spring AOP 使用一 个 Advice 作为拦截器,在 JoinPoint "周围"维护一系列 ...

  6. spring-boot-learning-使用jsp

    加入依赖: <!-- jsp--> <!--引入Spring Boot内嵌的Tomcat对JSP的解析包--> <dependency> <groupId&g ...

  7. 是否可以从一个静态(static)方法内部发出对非静态 (non-static)方法的调用?

    不可以,静态方法只能访问静态成员,因为非静态方法的调用要先创建对象,在 调用静态方法时可能对象并没有被初始化.

  8. SVN在idea中操作解析图

    进入的位置

  9. carsim笔记——道路设置

    第一步: 进入道路轨迹设置 道路情况设置举例 第二步:设置道路3D的显示效果 对上面的解释举例说明

  10. 排序 | 冒泡排序的优化与qsort快速排序

    冒泡排序 冒泡排序 Bubble_Sort,是极为简单的一种排序算法.虽然效率差一点,但好在具有结构简单,容易理解,易于操作等优点.冒泡排序就是把小的元素往前调或者把大的元素往后调.在相邻的两个元素间 ...