作者 |明明如月小角落
责编 | 屠敏
出品 | CSDN 博客
背景
下面给出一个例子,问输出的结果是多少:
publicclassIntTest{publicstaticvoidmain(String[]args){Integera=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) 构造(不信可以断点)。
/***Returnsan{@codeInteger}instancerepresentingthespecified*{@codeint}value.Ifanew{@codeInteger}instanceisnot*required,thismethodshouldgenerallybeusedinpreferenceto*theconstructor{@link#Integer(int)},asthismethodislikely*toyieldsignificantlybetterspaceandtimeperformanceby*cachingfrequentlyrequestedvalues.**Thismethodwillalwayscachevaluesintherange-128to127,*inclusive,andmaycacheothervaluesoutsideofthisrange.**@paramian{@codeint}value.*@returnan{@codeInteger}instancerepresenting{@codei}.*@since1.5*/publicstaticIntegervalueOf(inti){if(i>=IntegerCache.low&&i<=IntegerCache.high)returnIntegerCache.cache[i+(-IntegerCache.low)];returnnewInteger(i);}
通过源码和注释可以看到 如果是-128到127之间的整数,则会使用整数缓存对象,否则就new一个整形对象。
因此第一个是true,第二个是false。
反汇编
前面讲到了,用到了 再问一个问题 为什么调用了 java.lang.Integer#valueOf(int) ?
我们直接反汇编:javap -c IntTest
Compiledfrom"IntTest.java"mon.int_test.IntTest{mon.int_test.IntTest();Code:0:aload_01:invokespecial#1//Methodjava/lang/Object."<init>":()V4:returnpublicstaticvoidmain(java.lang.String[]);Code:0:bipush1002:invokestatic#2//Methodjava/lang/Integer.valueOf:(I)Ljava/lang/Integer;5:astore_16:bipush1008:invokestatic#2//Methodjava/lang/Integer.valueOf:(I)Ljava/lang/Integer;11:astore_212:sipush15015:invokestatic#2//Methodjava/lang/Integer.valueOf:(I)Ljava/lang/Integer;18:astore_319:sipush15022:invokestatic#2//Methodjava/lang/Integer.valueOf:(I)Ljava/lang/Integer;25:astore427:getstatic#3//Fieldjava/lang/System.out:Ljava/io/PrintStream;30:aload_131:aload_232:if_acmpne3935:iconst_136:goto4039:iconst_040:invokevirtual#4//Methodjava/io/PrintStream.println:(Z)V43:getstatic#3//Fieldjava/lang/System.out:Ljava/io/PrintStream;46:aload_347:aload449:if_acmpne5652:iconst_153:goto5756:iconst_057:invokevirtual#4//Methodjava/io/PrintStream.println:(Z)V60:return}
很明显四个Integer对象的构造使用了java/lang/Integer.valueOf函数。
那么除了上面的回答还有哪些更完善的回答呢?
我们继续看 java.lang.Integer.IntegerCache的源码
/***Cachetosupporttheobjectidentitysemanticsofautoboxingforvaluesbetween*-128and127(inclusive)asrequiredbyJLS.**Thecacheisinitializedonfirstusage.Thesizeofthecache*maybecontrolledbythe{@code-XX:AutoBoxCacheMax=<size>}option.*DuringVMinitialization,java.lang.Integer.IntegerCache.highproperty*maybesetandsavedintheprivatesystempropertiesinthe*sun.misc.VMclass.*/privatestaticclassIntegerCache{staticfinalintlow=-128;staticfinalinthigh;staticfinalIntegercache[];//省略}
可以看到可以通过设置虚拟机参数:XX:AutoBoxCacheMax=<size>或 -Djava.lang.Integer.IntegerCache.high=<high>
来设置缓存范围的最大值(包含)。
因此如果将最大值设置为150或者以上。则程序的答案就是 true, true。
另外缓存是 《Java语言规范》的要求,具体可以去语言规范里看。
这里提供手册的下载地址:/javase/specs/index.html
总结
我们看一些文章的时候,不要止步于文章给出的标准答案,否则总是“背”文章,印象不深刻。
最好自己能够动手DEMO一下,能过亲自去源码里看一看,能够有自己的思考,才能学得更多。
研究Java相关问题除了多看源码外,还可以多反汇编,不要惧怕,一回生两回熟,慢慢就会乐此不疲。
总之希望本文能够给大家一些启发,养成读源码,反汇编等好的学习方法,更快进阶。
声明:本文为 CSDN 博主「明明如月小角落」的原创文章,版权归作者所有,如需转载请联系作者。
原文:/w605283073/article/details/98475057
【END】
Google:这三个原因让我们死心塌地爱上Python!
/topic/python115?utm_source=csdn_bw
热 文推 荐
☞快手百度 4.34 亿美元投资知乎;腾讯回应“push团队全部被开”;Android Q Beta 6 发布 | 极客头条
Facebook 研发可穿戴脑机接口,读心术成真?
深度学习图像算法在内容安全领域的应用实践和优化
《乐队的夏天》很酷?程序员式的摇滚才燃爆了!
☞屌!小哥用 12 个月的时间开发了12款比特币Dapp, 0.00000001 BTC就能玩区块链版"蚂蚁庄园"
再见!微服务
☞没看完这11 条,别说你精通Python装饰器
第四范式戴文渊:AI落地,为什么不能照搬教科书?
边看边用!这本 Python 3.6 的书火爆了 IT 圈!
点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。
你点的每个“在看”,我都认真当成了喜欢