为什么等于运算符的Integer值直到128数?
为什么Integer “=”运算符不适用于128和Integer值之后? 有人可以解释这种情况吗?
这是我的Java环境:java版“1.6.0_37”
Java(TM)SE运行时环境(版本1.6.0_37-b06)
Java HotSpot(TM)64位服务器VM(内置20.12-b01,混合模式)
示例代码:
Integer a; Integer b; a = 129; b = 129; for (int i = 0; i < 200; i++) { a = i; b = i; if (a != b) { System.out.println("Value:"+ i + " - Different values"); } else { System.out.println("Value"+ i + " Same values"); } }
控制台输出的某些部分:
Value:124 - Same values Value:125 - Same values Value:126 - Same values Value:127 - Same values Value:128 - Different values Value:129 - Different values Value:130 - Different values Value:131 - Different values Value:132 - Different values
谢谢!
查看Integer的源代码 。 您可以在那里看到值的缓存。
只有在使用Integer.valueOf(int)
时才会发生缓存,而不是在使用new Integer(int)
。 您使用的自动装箱使用Integer.valueOf
根据JLS ,您可以始终指望对于介于-128和127之间的值,在自动装箱后获得相同的Integer对象,并且在某些实现中,即使对于更高的值,您也可能获得相同的对象。
实际上在Java 7中(我认为在较新版本的Java 6中),IntegerCache类的实现已经改变,上限不再是硬编码的,但可以通过属性“java.lang.Integer.IntegerCache”进行配置。高“,所以如果使用VM参数-Djava.lang.Integer.IntegerCache.high=1000
运行程序,则所有值都会得到”相同值“。
但是JLS仍然保证它直到127:
理想情况下,装箱给定的原始值p将始终产生相同的参考。 实际上,使用现有的实现技术可能不可行。 上述规则是务实的妥协。 上面的最后一个条款要求将某些常见值装入无法区分的对象中。 实现可以懒惰或急切地缓存这些。
对于其他值,此公式不允许对程序员的盒装值的身份进行任何假设。 这将允许(但不要求)共享部分或全部这些引用。
这确保了在大多数常见情况下,行为将是期望的行为,而不会造成过度的性能损失,尤其是在小型设备上。 例如,较少内存限制的实现可以缓存所有字符和短路,以及-32K – + 32K范围内的整数和长整数。
Integer
是int
的包装类。
Integer != Integer
比较实际的对象引用,其中int != int
将比较值。
如前所述,缓存了值-128到127,因此返回相同的对象。
如果超出该范围,将创建单独的对象,因此引用将不同。
要解决这个问题:
- 使类型为
int
或 - 将类型转换为
int
或 - 使用
.equals()
根据Java语言规范:
如果被装箱的值p为true,false,一个字节,范围为\ u0000到\ u007f的字符,或者介于-128和127之间的int或短号,则让r1和r2为任意两次装箱转换的结果of p。 始终是r1 == r2的情况。
JLS拳击转换
有关int缓存的更多信息,请参阅此文章
Integer对象具有内部缓存机制:
private static class IntegerCache { static final int high; static final Integer cache[]; static { final int low = -128; // high value may be configured by property int h = 127; if (integerCacheHighPropValue != null) { // Use Long.decode here to avoid invoking methods that // require Integer's autoboxing cache to be initialized int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} }
另见valueOf方法:
public static Integer valueOf(int i) { if(i >= -128 && i <= IntegerCache.high) return IntegerCache.cache[i + 128]; else return new Integer(i); }
这就是为什么你应该使用valueOf
而不是new Integer
。 Autoboxing使用此缓存。
另见这篇文章: https : //effective-java.com/2010/01/java-performance-tuning-with-maximizing-integer-valueofint/
使用==
不是一个好主意,使用equals比较值。
使用.equals()
而不是==
。
整数值仅缓存在-127和128之间的数字,因为它们最常用。
if (a.equals(b)) { ... }
根据您获取Integer
实例的方式,它可能不适用于任何值:
System.out.println(new Integer(1) == new Integer(1));
版画
false
这是因为应用于引用类型操作数的==
运算符与这些操作数表示的值无关。
这是因为Integer
类的实现逻辑。 它已准备好数字对象直到128.您可以查看http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/lang/Integer.java打开源例如-jdk(搜索cache [])。
基本上不应该使用==
来比较对象,只有Enums有一个例外。