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. dpwwn-01

    环境配置 靶机下载地址: https://download.vulnhub.com/dpwwn/dpwwn-01.zip 下载好解压打开.vmx文件即可 启动后如图: 无法直接获得靶机ip,用kali ...

  2. ctf之Flask_fileUpload

    启动环境,显示如图: 直接f12产看源码信息: 大致意思是:使用python编写文件然后以图片格式上传系统会以ipython格式解析,就可获取flag. 编写python代码: import os o ...

  3. Spark—GraphX编程指南

    Spark系列面试题 Spark面试题(一) Spark面试题(二) Spark面试题(三) Spark面试题(四) Spark面试题(五)--数据倾斜调优 Spark面试题(六)--Spark资源调 ...

  4. Mybatis配置错误:java.lang.ExceptionInInitializerError

    情况一:配置文件,无法被导出或者生效 修改前: 修改后: 究其原因,这是由于Maven的约定大于配置,导致我们写的配置文件,无法被导出或者生效的问题,解决方案: 在pom.xml文件中配置导出非res ...

  5. HyBird App(混合应用)核心原理JSBridge

    目录 app分类 HyBird App(混合应用) JSBridge介绍 优势及应用场景 JsBridge的核心 1.Web端调用Native端代码 1.1 拦截URL Schema 1.2 注入ap ...

  6. 中国软件杯---电力客户行为分析---图表联动echarts-demo(flask)

    中国软件杯---电力客户行为分析---图表联动echarts-demo(flask) 题目链接(可下载原始CSV数据集):http://www.cnsoftbei.com/plus/view.php? ...

  7. JS的Event各种属性级target/currentTarget/relatedTarget各种目录的解释

    1.Event属性解释:https://developer.mozilla.org/zh-CN/docs/Web/API/Event 2.Event.target/currentTarget/rela ...

  8. short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?

    对于short s1 = 1; s1 = s1 + 1;由于1是int类型,因此s1+1运算结果也是int 型,需要强制转换类型才能赋值给short型.而short s1 = 1; s1 += 1;可 ...

  9. java-設計模式-單例模式

    單例模式 一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点. 一个类只有一个实例,且该类能自行创建这个实例的一种模式. 簡單的對比就是: 例如,Windows 中 ...

  10. (转载) MOS管区分NP沟道

    三极管是流控型器件,MOS管是压控型器件,两者存在相似之处.三极管机可能经常用,但MOS管你用的可能较少.对于MOS管先抛出几个问题: 如何区分P-MOS和N-MOS:   如何区分MOS的G.D.S ...