Viv*_*vek 36 java integer constants
我无法理解Java Constant Pool for Integer的工作原理.
我理解字符串的行为,因此能够证明自己与Integer Constants的情况相同.
所以,对于整数
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1==i2); // True
Run Code Online (Sandbox Code Playgroud)
&
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1==i2); // False
Run Code Online (Sandbox Code Playgroud)
直到这里,一切都在我的脑海里.
我无法消化的是,当我从127增加整数时,它的行为有所不同.这种行为在127之后发生变化,下面是代码片段
Integer i1 = 128;
Integer i2 = 128;
System.out.println(i1==i2); // False. WHY?????
Run Code Online (Sandbox Code Playgroud)
有人可以帮我理解吗?
Jon*_*eet 45
不,数字的常量池与字符串的工作方式不同.对于字符串,仅实现编译时常量 - 而对于整数类型的包装类型,任何装箱操作将始终使用池(如果它适用于该值).例如:
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
Run Code Online (Sandbox Code Playgroud)
JLS保证了一小部分池化值,但如果愿意,实现可以使用更广泛的范围.
请注意,尽管不能保证,但我所看到的每个实现都Integer.valueOf用于执行装箱操作 - 因此您可以在没有语言帮助的情况下获得相同的效果:
Integer x = Integer.valueOf(100);
Integer y = Integer.valueOf(100);
System.out.println(x == y); // true
Run Code Online (Sandbox Code Playgroud)
如果被装箱值p为真,假,字节,或在范围\ u0000的一个char到\ u007f,或int或-128和127(含)之间的短号码,然后让r1和r2是的结果p的任何两个拳击转换.始终是r1 == r2的情况.
理想情况下,装箱给定的原始值p将始终产生相同的参考.实际上,使用现有的实现技术可能不可行.上述规则是一种务实的妥协.上面的最后一个条款要求将某些常见值装入无法区分的对象中.实现可以懒惰地或急切地缓存这些.对于其他值,此公式不允许对程序员的盒装值的身份进行任何假设.这将允许(但不要求)共享部分或全部这些引用.
这确保了在大多数常见情况下,行为将是期望的行为,而不会造成过度的性能损失,尤其是在小型设备上.例如,较少内存限制的实现可以缓存所有char和short值,以及-32K到+ 32K范围内的int和long值.
Ami*_*nde 20
Java维护整数池-128到127
像下面一样声明整数
Integer i1 = 127;
Run Code Online (Sandbox Code Playgroud)
结果到
Integer i1 = Integer.valueOf(127);
Run Code Online (Sandbox Code Playgroud)
那么第一种情况实际发生的是
Integer i1 = 127;<---Integer.valueOf(127);
Integer i2 = 127;<---Integer.valueOf(127);<---Same reference as first
Run Code Online (Sandbox Code Playgroud)
从Integer类 valueOf 方法的源代码
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
Run Code Online (Sandbox Code Playgroud)
因此,如果值介于-128to 之间,则会得到相同的引用,127并且您调用valueOfelse,它只返回new Integer(i)
并且因为引用相同,所以==运算符适用valueOf于此范围之间返回的整数.
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
Run Code Online (Sandbox Code Playgroud)
但是,当您使用newoperator 创建整数实例时,将在Heap上创建一个新对象.所以,
Integer i = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i == i2); // false
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19629 次 |
| 最近记录: |