最新消息:

在java中为何 1000 == 1000 返回 False, 而100 == 100 返回True

JAVA 大步 464浏览 0评论
未完全按照原文翻译,添加了部分自己的分析,有问题请留言。

执行如下代码:

返回结果为:

分析:

我们知道,当两个引用指向同一个对象的时候,使用 == 比较,则会返回true。如果两个引用指向不同的对象,则会返回false,即使它们的内容是相同的。按照这种理解,则前面代码的最后一句话应该返回false才是正确的,但是为何却返回true呢?

 

这就是这道题目有趣的原因。如果你去查看Integer.java类,你就会发现它里面还有一个私有的内部类,叫IntegerCache.java。这个内部类会缓存所有介于 -128~127之间的Integer对象。

 

 

 

所以,所有小的integer对象都会被缓存在内部,当我们如下声明的时候:

内部实际是做如下操作:

如果我们查看valueOf()方法,我们会看到:

如果这个值甲鱼 -128~127之间,则会从cache中返回实例,而不是新建一个实例。所以……

  1. Integer c = 100, d = 100;
实例c和d都是指向同一个对象,这就是为何
  1. System.out.println(c == d);
返回true的原因。

 

现在你可能会问,为什么Integer需要缓存?

 

嗯,逻辑上的理由是在-128~127返回内的小的integer比大的integer使用的更加频繁,因此,使用相同的底层对象是值得的,以减少潜在的内存占用。

然而,你可能会通过反射api滥用这一特性。

 

运行下面的代码,享受这一魔法:

运行结果:
before:newCache[132] =4
before:newCache[133] =5
after:newCache[132] =5
2 + 2 = 5

 
分析:
1.先通过反射获取IntegerCache内部的Integer cache[]数组。
2.newCache[133] 表示 cache中下标为133的数,则转换为实际的十进制是133-128=5
同理,newCache[132] 表示十进制的值是4。所以,执行:
newCache[132] = newCache[133]; 
newCache[132]的值就为5。
3.之所以打印b的值,会变成5,是因为System.out.printf()方法的参数必须是对象,而int类型的会被系统进行自动封箱成Integer类型对象,这样就会调用IntegerCache类中的cache数组,导致打印b的值为5。但是计算机中,int b 的实际值还是4,我们可以修改上面的代码,进行验证:
结果:
可以看到,如果int b的实际值不是4的话,则int c的就不可能是6。由此可以推断,int b在计算机内部的值实际是没变的。之所以print的结果不同,是因为print函数对int b进行了封箱操作,变成了Integer对象。
 
 
 
 

 

转载请注明:大步's Blog » 在java中为何 1000 == 1000 返回 False, 而100 == 100 返回True

SiteMap