整数包装对象只在值127内共享相同的实例?
在这里,他们是同一个实例:
Integer integer1 = 127; Integer integer2 = 127; System.out.println(integer1 == integer2); // outputs "true"
但在这里他们是不同的例子:
Integer integer1 = 128; Integer integer2 = 128; System.out.println(integer1 == integer2); // outputs "false"
为什么包装器对象只能在值127内共享相同的实例?
因为它是由Java语言规范指定的。
JLS 5.1.7拳击转换 :
如果值为
p
的值为true
,false
,byte
或范围在\u0000
到\u007f
之间的char
,或者介于-128和127之间的int
或short
数字,则令r 1
和r 2
为p
的任何两个拳击转换的结果。r 1 == r 2
总是这样的情况。理想情况下,装箱一个给定的原始值
p
,总会产生一个相同的参考。 实际上,使用现有的实现技术可能是不可行的。 上面的规则是一个务实的妥协。 上面的最后一个条款要求某些常用值总是被装入不可区分的对象中。 实现可能会缓存这些,懒惰或热切。 对于其他值,这个公式不允许对程序员的盒装值的身份进行任何假设。 这将允许(但不要求)分享这些引用的一部分或全部。这确保了在大多数情况下,行为将是所期望的,而不施加不适当的性能损失,特别是在小型设备上。 例如,内存限制较少的实现可能会缓存所有
char
和short
值,以及-32K到+ 32K范围内的int
和long
值。
java.lang.Integer的来源:
public static Integer valueOf(int i) { final int offset = 128; if (i >= -128 && i <= 127) { // must cache return IntegerCache.cache[i + offset]; } return new Integer(i); }
干杯!
顺便说一句,你可以缩短你的代码
System.out.println("Integer 127 == " + ((Integer) 127 == (Integer) 127)); System.out.println("Integer 128 == " + ((Integer) 128 == (Integer) 128)); for(int i=0;i<5;i++) { System.out.println( "Integer 127 system hash code " + System.identityHashCode((Integer) 127) + ", Integer 128 system hash code "+System.identityHashCode((Integer) 128)); }
版画
Integer 127 == true Integer 128 == false Integer 127 system hash code 1787303145, Integer 128 system hash code 202703779 Integer 127 system hash code 1787303145, Integer 128 system hash code 1584673689 Integer 127 system hash code 1787303145, Integer 128 system hash code 518500929 Integer 127 system hash code 1787303145, Integer 128 system hash code 753416466 Integer 127 system hash code 1787303145, Integer 128 system hash code 1106961350
你可以看到127每次都是同一个对象,而128的对象是不同的。
因为[-128,127]范围内的小值被缓存,而较大的值不被存储。
为了包装整数,Java使用http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html#valueOf%28int%29
除了其他的答案,我想补充说==
只比较对象引用。 使用.equals()
来代替:
Integer integer1=128; Integer integer2=128; if(integer1.equals(integer2)) System.out.println(true); else System.out.println(false);