IntegerCache的妙用和陷阱!

考虑下面的小程序,你认为会输出为什么结果?

public class Test { public static void main(String[] args) { Integer n1 = 123; Integer n2 = 123; Integer n3 = 128; Integer n4 = 128; System.out.println(n1 == n2); System.out.println(n3 == n4); } }

答案如下,请选择刮开:

true

false

是否和你预想的一致?

我们知道==比较的是对象的引用,那这里为什么会这出这种情况呢?

原理

首先这是JDK在1.5版本中添加的一项新特性,把-128~127的数字缓存起来了,用于提升性能和节省内存。所以这个范围内的自动装箱(相当于调用valueOf(int i)方法)的数字都会从缓存中获取,返回同一个数字,所以现在你理解为什么了吧。同时这也会给我们开发带来预想不到的陷阱,直得注意!!

而我们通过new Integer(1)这样就不会从缓存中获取,大家可以自行测试。

我们来翻看下jdk中Integer的源码

上面是IntegerCache的源码,把从-128~high放在缓存中

上面是valueOf的源码,先从缓存中获取,获取不到再new一个返回

从源码里面我们可以看到最小边界是-128,最大边界可以通过-XX:AutoBoxCacheMax进行配置,但也不会大于Integer.MAX_VALUE最大值。

扩展 这种缓存行为不仅用于Integer类,而且还用于Long,Short,Byte,Character,大家可以去这些类里面查看XxxCache的类和valueOf方法源码,原理大致相同,但它们的边界略有一二,也不能进行最大边界的配置。

原文发布于微信公众号 - Java技术栈(javastack)

原文发表时间:2017-05-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Python小屋

详解Python变量作用域

本文暂时不讨论类定义中的变量(成员)作用域,改天可能会单独成文介绍。 变量作用域总起来说可以这么理解:1)在函数内如果只引用某个变量的值而没有为其赋新值,该变量...

51180
来自专栏Linux驱动

C语言异常处理之 setjmp()和longjmp()

异常处理之除0情况 相信大家处理除0时,都会通过函数,然后判断除数是否为0,代码如下所示: double divide(doublea,double b) { ...

35140
来自专栏java一日一条

Java 多线程并发编程之 Synchronized 关键字

现有一成员变量 Test,当线程 A 调用 Test 的 synchronized 方法,线程 A 获得 Test 的同步锁,同时,线程 B 也去调用 Test...

24920
来自专栏数据结构与算法

3186 队列练习 2

3186 队列练习 2 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description (此题...

26950
来自专栏aCloudDeveloper

string 之 strrev函数

Author: bakari  Date: 2012/8/9 继上篇。。。。。 下面是我写的代码与源码作的一些比较,均已严格测试通过,分别以“string 之”...

19690
来自专栏情情说

深入浅出MyBatis:反射和动态代理

前三篇详细总结了Mybatis的基本特性、常用配置、映射器,相对于Hibernate,映射器的配置相对复杂,但有很好的灵活性和扩展性,可以应对各种业务场景。熟练...

46670
来自专栏云霄雨霁

SpringMVC--参数绑定笔记

22300
来自专栏从零开始学 Web 前端

09 - JavaSE之线程

PS: 如果我们没有 new一个 Thread 对象出来,而是直接使用 MyThread 的 run 方法(mt.run()),这就是方法调用,而不是启动线程了...

14750
来自专栏向治洪

java造成内存泄露原因

一、Java内存回收机制  不论哪种语言的内存分配方式,都需要返回所分配内存的真实地址,也就是返回一个指针到内存块的首地址。Java中对象是采用new或者反射的...

307100
来自专栏别先生

python的学习和使用

17300

扫码关注云+社区

领取腾讯云代金券