为什么是128==128假,但127==127是真实的比较时整数包装在Java?
-
19-09-2019 - |
题
class D {
public static void main(String args[]) {
Integer b2=128;
Integer b3=128;
System.out.println(b2==b3);
}
}
输出:
false
class D {
public static void main(String args[]) {
Integer b2=127;
Integer b3=127;
System.out.println(b2==b3);
}
}
输出:
true
注:之间的数字-128和127是真实的。
解决方案
当你汇编一个数字在Java,并将其分配给一个整数(资本 I
)编译器发出:
Integer b2 =Integer.valueOf(127)
这一行代码也是产生当使用自动装箱.
valueOf
是实施使得某些数字被"集中",它返回同一个实例为数值小于128.
从java1.6源代码线621:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
值 high
可配置到另一个价值,该系统属性。
-Djava.郎。整数。IntegerCache.高=999
如果你行你的计划与该系统属性,它将输出是真的!
显而易见的结论:永远不要依赖两个参考文献被完全相同,总是比较他们 .equals()
法。
所以 b2.equals(b3)
将打印适用于所有逻辑上的平等价值观的b2、b3。
注意, Integer
高速缓存是不是有针对性的原因,而是符合的 捷尔思,部分5.1.7;对象的身份,必须给予值在-128至127包容性。
整#值(int) 还文件的这一行为:
这种方法可能会产生显着更好的空间和时性的缓存经常请求的价值观。这种方法将始终缓值范围在-128至127、包容和可能的缓存的其他值此之外的范围。
其他提示
自动装箱缓存在-128 127。这是规定在家乐仕(5.1.7).
如果值 p 正在装箱的是真的,假,一个字一个字符的范围\u0000以\u007f,或者一个int或短之间的数字-128和 127,然后让r1和r2会结果的任何两个拳击转换 p.这是总的情况,r1==r2。
一个简单的规则,还记得当处理的对象是使用 .equals
如果你想检查,如果两个物体都是"平等",使用 ==
当你想要看看他们是否指向同一个实例。
使用原始数据类型,整数,将在两种情况下产生真实的,期望的输出。
然而,因为您使用的整数对象==操作具有不同的含义。
在对象的上下文中,==检查是否变量是指相同的对象引用。
要比较应使用等于对象的值()方法 E.g。
b2.equals(b1)
这将表明B2是否小于B1,大于或等于(检查细节API)
有在Java内存优化相关。
要节省存储器,Java的重复使用'所有的包装对象,其值 落入以下范围:
所有布尔值(真和假)
所有的字节值
这\ u0000的所有字符值到\ u007f(即0到十进制127)
所有短期和整数值从-128到127。
看一下Integer.java,如果值在-128到127之间,它将使用缓存池,所以 (Integer) 1 == (Integer) 1
尽管 (Integer) 222 != (Integer) 222
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
我写以下作为这个问题不只是特定于整数。我的结论是,更多的往往不是,如果你使用的API不正确,你窗台看到不正确的行为。正确地使用它,你应该看到正确的行为:
public static void main (String[] args) {
Byte b1=127;
Byte b2=127;
Short s1=127; //incorrect should use Byte
Short s2=127; //incorrect should use Byte
Short s3=128;
Short s4=128;
Integer i1=127; //incorrect should use Byte
Integer i2=127; //incorrect should use Byte
Integer i3=128;
Integer i4=128;
Integer i5=32767; //incorrect should use Short
Integer i6=32767; //incorrect should use Short
Long l1=127L; //incorrect should use Byte
Long l2=127L; //incorrect should use Byte
Long l3=13267L; //incorrect should use Short
Long l4=32767L; //incorrect should use Short
Long l5=2147483647L; //incorrect should use Integer
Long l6=2147483647L; //incorrect should use Integer
Long l7=2147483648L;
Long l8=2147483648L;
System.out.print(b1==b2); //true (incorrect) Used API correctly
System.out.print(s1==s2); //true (incorrect) Used API incorrectly
System.out.print(i1==i2); //true (incorrect) Used API incorrectly
System.out.print(l1==l2); //true (incorrect) Used API incorrectly
System.out.print(s3==s4); //false (correct) Used API correctly
System.out.print(i3==i4); //false (correct) Used API correctly
System.out.print(i5==i6); //false (correct) Used API correctly
System.out.print(l3==l4); //false (correct) Used API correctly
System.out.print(l7==l8); //false (correct) Used API correctly
System.out.print(l5==l6); //false (correct) Used API incorrectly
}