整数包装对象仅在值 127 内共享相同的实例? [复制]
Posted
技术标签:
【中文标题】整数包装对象仅在值 127 内共享相同的实例? [复制]【英文标题】:Integer wrapper objects share the same instances only within the value 127? [duplicate] 【发布时间】:2011-07-04 06:43:01 【问题描述】:这里它们是同一个实例:
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 内共享同一个实例?
【问题讨论】:
【参考方案1】:因为它是由 Java 语言规范指定的。
JLS 5.1.7 Boxing Conversion:
如果值
p
被装箱是true
、false
、byte
或char
在\u0000
到\u007f
范围内,或int
或short
介于 -128 和 127(含)之间的数字,然后让r<sub>1</sub>
和r<sub>2</sub>
成为p
的任意两次装箱转换的结果。r<sub>1</sub> == r<sub>2</sub>
总是如此。理想情况下,将给定的原始值
p
装箱将始终产生相同的引用。在实践中,使用现有的实现技术这可能是不可行的。上述规则是务实的妥协。上面的最后一个子句要求某些公共值总是被装箱到无法区分的对象中。实现可能会懒惰地或急切地缓存这些。对于其他值,此公式不允许程序员对装箱值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。这可确保在大多数常见情况下,行为将是期望的行为,而不会造成过度的性能损失,尤其是在小型设备上。例如,内存限制较少的实现可能会缓存所有
char
和short
值,以及 -32K 到 +32K 范围内的int
和long
值。
【讨论】:
请注意,JLS 指定 minimum 缓存/实习范围,而不是 maximum(见最后一句)......所以它在技术上是“由实施”;-) 他们为什么会这样?看不懂 然后想一想:他们所要做的就是允许运算符重载,而这些都无法在 JNI 之外检测到。【参考方案2】: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);
干杯!
【讨论】:
Java 6 最新版本支持将最大缓存值更改为大于 127。【参考方案3】:顺便说一句,您可以将代码缩短为
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的对象是不同的。
【讨论】:
【参考方案4】:因为 [-128, 127] 范围内的小值会被缓存,而更大的值不会被缓存。
为了包装整数,Java 使用http://download.oracle.com/javase/6/docs/api/java/lang/Integer.html#valueOf%28int%29
【讨论】:
请问cached是什么意思 它只是一个在加载 Integer 类时创建并初始化的数组。 他们为什么会这样?看不懂 经常使用小数字(例如在计算中),这可以防止JVM在每次x + 1完成时分配一个新对象。【参考方案5】:除了我想补充的其他答案之外,==
仅比较对象引用。请改用.equals()
:
Integer integer1=128;
Integer integer2=128;
if(integer1.equals(integer2))
System.out.println(true);
else
System.out.println(false);
【讨论】:
以上是关于整数包装对象仅在值 127 内共享相同的实例? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
为啥在比较 Java 中的整数包装器时 128==128 为假但 127==127 为真?
仅在对象实例的生命周期内保持 Python 解释器处于活动状态