听说Integer有bug?1000不等于1000?
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吗?
到此,我们已经得知,几个重点:
- Integer 是对象
- Integer 值比较应该使用 equals()
- Integer 有个缓存池 IntegerCache,预初始化 -127 至 127 的 Integer 对象\
再看看demo,使用的是“==”并不是“equals()”,所以这并不是bug,而是比较的方式不对,正确的比较姿势是“equals()”,我们来实践一下看看。
举一反三
同样是装箱拆箱,Long是否也有缓存池呢?Double呢?
My Blog
技术交流
听说Integer有bug?1000不等于1000?的更多相关文章
- 糟糕,你写的 BUG 要被存1000年了!
摘要:代码冰封,祖传千年! 把大象放在冰箱需要几步? 三步!把代码放在北极需要几步?纳尼? GitHub刚刚公布了一组照片,你写的代码(BUG)上周已经被打包运往北极保存. 只要你2月2日以前贡献过的 ...
- hide(1000)跟show(1000)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- NGUI panel 之下widget最大depth是1000,超过1000时OnClick会出问题!
经过我的测试发现ngui widget的depth是有限制的!原本以为只要不同panel间的depth设置好了后无论widget depth如何设置都没问题,直到我们项目中出现奇怪的点击问题后才发现这 ...
- Java Integer于Int 进行==双等于的内存比较时的一些问题说明
转自: https://blog.csdn.net/xingkongdeasi/article/details/79618421 部分有所修改: 前言: 越是简单的东西,我们往往越是没有去把它明白,但 ...
- java 中 sleep(1000) 和 wait(1000) 的区别?
1.首先 sleep 方法是Thread类中的静态方法,他的作用是使当前线程暂时睡眠指定的时间,可以不用放在synchronized方法或者代码块中,但是 wait 方法是Object类的方法,它是使 ...
- 验证HashSet和HashMap不是线程安全
JAVA集合类: java.util包下的HashSet和HashMap类不是线程安全的, java.util.concurrent包下的ConcurrentHashMap类是线程安全的. 写2个测试 ...
- Java基础教程——包装类
Java出道之时,自诩为"纯面向对象的语言",意思是之前的所谓"面向对象语言"不纯. 但是,有人指责Java也不纯--8种基本类型并非类类型.为此,Java为他 ...
- C++ 类类型转换函数explicit 关键字
标准数据之间会进行 隐式类型安全转换. 转换规则: 隐式类型转换的问题: #include <iostream> #include <string> using namesp ...
- 计算机中K到底是1000还是1024?
1000和1024的争论,其实是传输领域和存储领域概念不清引起的;在传输领域,1秒钟传输多少字位(即b,bit),肯定是用10进制表示,所以是1kb=1000b,即1秒钟传输1000个比特位;就好像: ...
随机推荐
- jdr挖的大坑
计数问题小结 很多计数问题在直接拆分计算贡献时都会出现不容易直接表示的情况.在解决这些问题时,往往需要解决一些子问题方案数的递推, 再套用组合数或者分块计算来降低难度或时间复杂度,这里给出几种递推方法 ...
- 如何处理异形屏iphone X?
safe area: 默认放置在安全区域以避免遮挡, 但会压缩 在meta中添加viewport-fit=cover: 告诉浏览器要讲整个页面渲染到浏览器中,不管设备是圆角与否,这个时候会造成页面的元 ...
- CSS3实现环形进度条?
两个对半矩形遮罩, 使用rotate以及overflow: hidden进行旋转
- 说说对 SQL 语句优化有哪些方法?(选择几条)
1.Where 子句中:where 表之间的连接必须写在其他 Where 条件之前,那些可 以过滤掉最大数量记录的条件必须写在 Where 子句的末尾.HAVING 最后. 2.用 EXISTS 替代 ...
- Oracle入门基础(十三)一一java调用oracle存储过程
package demo; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.ResultS ...
- 转载:STL四种智能指针
转载至:https://blog.csdn.net/K346K346/article/details/81478223 STL一共给我们提供了四种智能指针: auto_ptr.unique_ptr.s ...
- 详解AOP——用配置文件的方式实现AOP
AOP概念 1.AOP:面向切面(方面)编程,扩展功能不修改源代码实现 AOP原理 AOP采用横向抽取机制,取代了传统纵向继承体系重复性代码 传统的纵向抽取机制: 横向抽取机制: AOP操作术语 1. ...
- MyBatis Plus 2.3 个人笔记-02-基本注解
实体类注解 /* * MybatisPlus会默认使用实体类的类名到数据中找对应的表. * */ @TableName("tbl_employee") public class E ...
- centos下安装配置maven
下载maven安装包 wget http://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.3.9/binaries/apache-maven ...
- String工具类之“四个判空方式”StringUtils.isNotBlank和StringUtils.isEmpty和StringUtils.isBlank和StringUtils.isNotEmpty
一.判断str字符串都不为空==>StringUtils.isNotBlank(String str); 1 /** 2 * <p>检查一个字符串是否非空("") ...