这个问题已经在这里有一个答案:
- 为什么在Java中比较整数包装时128 == 128假的,但127 == 127是真的吗? 6个回答
为什么整数“=”操作不为128的整数值后工作? 有人可以解释这种情况呢?
这是我的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.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是真,假字节,在范围\ u0000的一个char到\ u007f,或-128和127之间int或短号码,然后让r1和r2是任何两个装箱转换的结果的页。 它始终是R1 R2 = =的情况。
JLS装箱转换
请参阅这篇文章,INT缓存的更多信息
在整数对象具有一个内部高速缓存机制:
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
。 自动装箱使用此高速缓存。
也看到这个帖子: https://effective-java.com/2010/01/java-performance-tuning-with-maximizing-integer-valueofint/
使用==
是不是一个好主意,使用等于比较值。
使用.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例如(搜索缓存[])。
不应使用比拟的基本对象==
可言,但有一个例外,以枚举。