当前位置: 首页 > 科技观察

奇怪的Java问题:为什么128==128返回False,而127==127返回True?

时间:2023-03-22 16:36:38 科技观察

这就是我们今天要讨论的话题,因为我觉得很有意思。如果运行以下代码:classA{publicstaticvoidmain(String[]args){Integera=128,b=128;System.out.println(a==b);Integerc=127,d=127;System.out.println(c==d);}}你会得到如下结果:falsetrue我们知道,如果两个引用指向同一个对象,那么==就是true;反之,如果两个引用指向不同的对象,那么==为true为False,即使两个引用的内容相同。因此,结果将是错误的。这就是它变得非常有趣的地方。如果你查看Integer.java类,你会发现IntegerCache.java内部私有类为-128到127之间的所有整数对象提供缓存。这个东西为那些值相对较小的整数提供内部缓存。当做出这样的声明时:Integerc=127,它的内部是这样的:Integervar3=Integer.valueOf(127);其实我反编译A.class文件后,代码如下:如果观察valueOf()类函数,可以看到:publicstaticIntegervalueOf(inti){if(i>=IntegerCache.low&&i<=IntegerCache.high)returnIntegerCache.cache[i+(-IntegerCache.low)];returnnewInteger(i);}如果值介于-128和127之间,则返回缓存的实例。所以。..Integerc=127,d=127;两者都指向同一个对象。这就是为什么以下代码的结果为真:System.out.println(c==d);现在你可能会问,为什么要为-128到127之间的所有整数设置缓存?这是因为在这个范围内的Decimal-valuedintegers在日常生活中的使用频率远远高于其他值,并且多次使用同一个底层对象的特性可以通过这个设置来进行有效的内存优化。您可以使用反射API任意使用此功能。运行下面的代码,您将看到它是如何工作的。publicstaticvoidmain(String[]args)throwsNoSuchFieldException,IllegalAccessException{Classcache=Integer.class.getDeclaredClasses()[0];FieldmyCache=cache.getDeclaredField("cache");myCache.setAccessible(true);整数[]newCache=(整数[])myCache.get(cache);newCache[132]=newCache[133];inta=2;intb=a+a;System.out.printf("%d+%d=%d",a,a,b);//}打印出来的结果竟然是:2+2=5我们再看看反汇编代码:是不是和上面一样的问题?但为什么结果是2+2=5?我们继续看Integer源码,深入了解Integer缓存机制。下面截图:根据源码可以发现修改Integer缓存上限的方法有点瑕疵。我们来看看Api给我们的提示:缓存的大小可以通过{@code-XX:AutoBoxCacheMax=}选项来控制。原来我们只需要:在运行时设置-XX:AutoBoxCacheMax=133就OK了。

最新推荐
猜你喜欢