我无法理解Java Constant Pool for Integer的工作原理。
我理解字符串的行为,因此能够证明自己与整数常量的情况相同。
所以,对于整数
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1==i2); // True
&安培;
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1==i2); // False
直到这里,一切都在我的脑海里。
我无法消化的是,当我从127增加整数时,它的行为有所不同。此行为在127之后发生变化,下面是代码片段
Integer i1 = 128;
Integer i2 = 128;
System.out.println(i1==i2); // False. WHY?????
有人能帮我理解吗?
答案 0 :(得分:44)
不,数字的常量池与字符串的工作方式不同。对于字符串,只有编译时常量被实现 - 而对于整数类型的包装类型,任何装箱操作总是使用该池,如果它适用于该值。例如:
int x = 10;
int y = x + 1;
Integer z = y; // Not a compile-time constant!
Integer constant = 11;
System.out.println(z == constant); // true; reference comparison
JLS保证了一小部分池化值,但如果愿意,实现可以使用更广泛的范围。
请注意,尽管不能保证,但我所看到的每个实现都使用Integer.valueOf
来执行装箱操作 - 所以在没有语言帮助的情况下你可以获得相同的效果:
Integer x = Integer.valueOf(100);
Integer y = Integer.valueOf(100);
System.out.println(x == y); // true
如果装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或者介于-128和127(含)之间的整数或短数,则让r1和r2为p的任意两次拳击转换的结果。始终是r1 == r2。
的情况理想情况下,装箱给定的原始值p将始终产生相同的参考。实际上,使用现有的实现技术可能不可行。上述规则是一种务实的妥协。上面的最后一个条款要求将某些常见值装入无法区分的对象中。实现可以懒惰地或急切地缓存这些。对于其他值,此公式不允许对程序员的盒装值的身份进行任何假设。这将允许(但不要求)共享部分或全部这些引用。
这确保了在大多数情况下,行为将是所需的行为,而不会造成过度的性能损失,尤其是在小型设备上。例如,较少内存限制的实现可以缓存所有char和short值,以及-32K到+ 32K范围内的int和long值。
答案 1 :(得分:19)
Java维护从-128
到127
如下所示声明整数
Integer i1 = 127;
结果
Integer i1 = Integer.valueOf(127);
所以第一种情况实际发生的是
Integer i1 = 127;<---Integer.valueOf(127);
Integer i2 = 127;<---Integer.valueOf(127);<---Same reference as first
来自Integer
类valueOf
方法的源代码
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
如果值介于-128
到127
之间,并且您调用valueOf
,则会获得相同的引用,否则它只返回new Integer(i)
因为引用相同,所以==
运算符适用于valueOf
在此范围之间返回的整数。
答案 2 :(得分:8)
Java缓存-128 to 127
范围内的整数对象。因此,当您尝试将此范围中的值分配给wrapper
对象时,boxing
操作将调用Integer.valueOf
方法,然后它将分配对已在该对象中的对象的引用池。
另一方面,如果您将此范围之外的值指定为wrapper
引用类型,Integer.valueOf
将为该值创建新的Integer
对象。因此,比较具有此范围之外的值的reference
个Integer
对象将为您提供false
所以,
Integer i = 127; --> // Equivalent to `Integer.valueOf(127)`
Integer i2 = 127;
// Equivalent to `Integer.valueOf(128)`
// returns `new Integer(128)` for value outside the `Range - [-128, 127]`
Integer i3 = 128;
Integer i4 = 128;
System.out.println(i == i2); // true, reference pointing to same literal
System.out.println(i3 == i4); // false, reference pointing to different objects
但是,当您使用new
运算符创建整数实例时,将在Heap上创建一个新对象。
所以,
Integer i = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i == i2); // false
答案 3 :(得分:2)
简而言之,较新版本的Java缓存Integer在-128到127范围内(256个值)。 看这里