java integer 缓存_你真的理解 Integer 的缓存问题吗?|CSDN 博文精选

48cc7af93a712ce18be4b4ecaaafd560.png

作者 | 明明如月小角落

责编 | 屠敏

出品 | CSDN 博客

背景

下面给出一个例子,问输出的结果是多少:

publicclassIntTest {publicstaticvoidmain(String[] args) { Integer a = 100, b = 100, c = 150, d = 150; System.out.println(a == b); System.out.println(c == d); }}

很多新手可能非常犹豫,有一些经验的同学可以回答出"标准"答案。

问原因则随口就说”Integer缓存了-128到127之间的整数对象“,为什么会缓存?还有其他答案?可能就不知道了。

what??? 难道这不是标准答案?还想咋地?

分析

运行

想知道答案很容易,直接运行,结果是 true ,false。

源码法

直接看源码, 我们知道声明整数时,会通过 java.lang.Integer#valueOf(int) 构造(不信可以断点)。

/** * Returns an {@code Integer} instance representing the specified * {@code int} value. If a new {@code Integer} instance is not * required, this method should generally be used in preference to * the constructor {@link #Integer(int)}, as this method is likely * to yield significantly better space and time performance by * caching frequently requested values. * * This method will always cache values in the range -128 to 127, * inclusive, and may cache other values outside of this range. * * @param i an {@code int} value. * @return an {@code Integer} instance representing {@code i}. * @since 1.5 */publicstatic Integer valueOf(int i){if (i >= IntegerCache.low && i <= IntegerCache.high)return IntegerCache.cache[i + (-IntegerCache.low)];returnnew Integer(i); }

通过源码和注释可以看到 如果是-128到127之间的整数,则会使用整数缓存对象,否则就new一个整形对象。

因此第一个是true,第二个是false。

反汇编

前面讲到了,用到了 再问一个问题 为什么调用了 java.lang.Integer#valueOf(int) ?

我们直接反汇编:javap -c IntTest

Compiled from "IntTest.java"publicclasscom.chujianyun.common.int_test.IntTest {public com.chujianyun.common.int_test.IntTest(); Code:0: aload_01: invokespecial #1// Method java/lang/Object."":()V4: returnpublicstaticvoid main(java.lang.String[]); Code:0: bipush 1002: invokestatic #2// Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;5: astore_16: bipush 1008: invokestatic #2// Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;11: astore_212: sipush 15015: invokestatic #2// Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;18: astore_319: sipush 15022: invokestatic #2// Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;25: astore 427: getstatic #3// Field java/lang/System.out:Ljava/io/PrintStream;30: aload_131: aload_232: if_acmpne 3935: iconst_136: goto4039: iconst_040: invokevirtual #4// Method java/io/PrintStream.println:(Z)V43: getstatic #3// Field java/lang/System.out:Ljava/io/PrintStream;46: aload_347: aload 449: if_acmpne 5652: iconst_153: goto5756: iconst_057: invokevirtual #4// Method java/io/PrintStream.println:(Z)V60: return}

很明显四个Integer对象的构造使用了java/lang/Integer.valueOf函数。

那么除了上面的回答还有哪些更完善的回答呢?

我们继续看 java.lang.Integer.IntegerCache的源码

/** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. The size of the cache * may be controlled by the {@code -XX:AutoBoxCacheMax=} option. * During VM initialization, java.lang.Integer.IntegerCache.high property * may be set and saved in the private system properties in the * sun.misc.VM class. */privatestaticclassIntegerCache{staticfinal int low = -128;staticfinal int high;staticfinal Integer cache[];// 省略}

可以看到可以通过设置虚拟机参数:XX:AutoBoxCacheMax=或 -Djava.lang.Integer.IntegerCache.high=

来设置缓存范围的最大值(包含)。

因此如果将最大值设置为150或者以上。则程序的答案就是 true, true。

另外缓存是 《Java语言规范》的要求,具体可以去语言规范里看。

这里提供手册的下载地址:https://docs.oracle.com/javase/specs/index.html

77bdea1c9a7858569d11af42968faab9.png

6e363a232394156919c4726ffcaaf779.png

总结

我们看一些文章的时候,不要止步于文章给出的标准答案,否则总是“背”文章,印象不深刻。

最好自己能够动手DEMO一下,能过亲自去源码里看一看,能够有自己的思考,才能学得更多。

研究Java相关问题除了多看源码外,还可以多反汇编,不要惧怕,一回生两回熟,慢慢就会乐此不疲。

总之希望本文能够给大家一些启发,养成读源码,反汇编等好的学习方法,更快进阶。

声明:本文为 CSDN 博主「明明如月小角落」的原创文章,版权归作者所有,如需转载请联系作者。

原文:https://blog.csdn.net/w605283073/article/details/98475057

【END】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值