我被凯西塞拉利昂和Bert贝茨读取SCJP Java 6中,这本书是混淆了我这么多。 在245页,他们指出下面的下面的代码。
Integer i1 = 1000;
Integer i2 = 1000;
if(i1 != i2)
System.out.println("different objects");
//Prints output
different objects
然后第二天页面上,他们有以下代码
Integer i3 = 10;
Integer i4 = 10;
if(i3 == i4)
System.out.println("same objects");
//Prints output
same objects
我很困惑! 当我尝试了这一点,我自己看来,你不能使用==你会用等于同样的方式()方法进行比较。 使用==总是给我“假”即使整型变量设置为相同的值(即10)。 我对么? 使用==来比较相同的整数对象(同一值)总是会导致“假”
Answer 1:
答案的关键在于所谓的对象实习 。 爪哇实习生小数目(小于128),因此,所有的实例Integer(n)
与n
在实习范围是相同的。 数大于或等于128不实习,因此Integer(1000)
对象不彼此相等。
Answer 2:
如果你看一下源代码Integer
你会发现Integer.valueOf(int)
池中的所有值-128到127的原因是,小的整数值被频繁使用,因此值得被汇集/缓存。
来自直Integer.java
:
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
请注意,这个池为特定实现,有没有合并范围的保证。
关于实习的答案是在概念上是正确的,但不正确的使用术语。 在Java中通常实习意味着Java运行时正在执行的池(如String的实习)。 在整数的情况下,它是做池类本身。 有没有JVM魔法参与。
Answer 3:
关于实习以上的答案是正确的。 如果你要考虑的事情,但:
Integer i3 = new Integer(10);
Integer i4 = new Integer(10);
你会不会有新的对象,因为你已经创建新对象显式。 如果你写的代码如下它将被拘禁:
Integer i3 = Integer.valueOf(10);
Integer i4 = Integer.valueOf(10);
现在他们将再次同一个对象。 如果你看一看的valueOf方法一样在src.zip文件中Integer.java类里面你可以看到,它检查看是否整型值是-128以外的127,它调用新的Integer类,否则它从缓存中加载它。
Answer 4:
Integer i1 = 1000;
Integer i2 = 1000;
编译器“方框”整型1000作为整数对象。 要做到这一点,输入源转换成如下:
Integer i1 = Integer.valueOf(1000);
Integer i2 = Integer.valueOf(1000);
现在valueOf
可能是一个简单的调用new Integer(1000)
但每次的时间来创建一个新的Integer对象int
是盒装要花费时间和空间。 为了避免这种情况Integer类保持整数对象数组对于int值的有限范围。
if(value> maxRange || value< minRange){
//not in pool return new Integer
return new Integer(value);
}else{
//return pooled Integer object
//for the value, pool contains all Integer
//values from minRange to maxRange
return integerPool[value-minRange];
}
获得与丢失该存储器中的速度可以通过在程序开始(AFAIK默认为-127至128)设定的范围内与JVM参数进行调整。
Answer 5:
当Java ==操作符用来比较较原始类型的其他任何东西,它会检查参考平等; 即使所比较的东西都包裹元适用。 此外, valueOf
生成编译器自动装箱声明的方法和通常不含任意返回一个新对象,将不参考等于任何其它先前存在的参考,或参考返回到现有的对象(这将当然,是基准等于任何预先存在的参考识别相同的对象)。 实现都必须保持一个“池” Integer
实例为值-128到127,这样将所有来电Integer.valueOf
在该范围内的任何具体数量将返回引用同一个对象,但除此之外的实施将免费做这样的事情
static Integer [] intPool = new Integer[256];
public Integer valueOf(int n)
{
int hash = (n*0x18675309) >>> 24;
Integer instance = intPool[n];
if (instance == null && instance.value != n)
{
instance = new Integer(n);
intPool[hash] = instance ;
}
return instance;
}
我不是特别期望的Java实现做这样的事情,因为在许多情况下,“缓存命中”率可能接近0%和额外的时间花在寻找缓存实例将被浪费。 然而,从未有任何保证,通过返回的引用instanceOf
不匹配此方法(即使它不通过该方法返回的最后一个参考匹配回到以前的一些参考,一些缓存算法有可能会导致它返回一个早参考,特别是在游泳池被多个线程没有锁定共享。缺乏锁定绝不会导致代码返回其他任何东西,而不是正确的值的整数的引用,但可能会导致在返回引用比较平等的不可预测的变化)。 仅参考Integer
使用构造直接创建的对象new Integer(n)
保证是唯一的; 其预期在返回的任何参考码valueOf
不匹配由返回的任何参考valueOf
具有实际观察到的,没有它不匹配,应考虑破碎。
Answer 6:
字符串比较和整数比较使用==和!=给出布尔结果并不如我们expect.So要小心,确保可能的未知的结果不会妨碍你的软件的性能,可靠性和准确性。
Answer 7:
“==”总是比较存储器位置或对象中的引用。 equals方法总是比较values.but也等于间接地使用“==”操作符来比较值。 整数使用整数高速缓存中的值-128存储+ 127.If ==操作符是用来之间-128到127,然后返回true检查任何价值。 如果-128之间的任何值到127
Integer i1 = -128;
Integer i2 = -128;
System.out.println(i1 == i2); // returns true
超过上述范围的其他则返回假
Integer i1 = 1000;
Integer i2 = 1000;
System.out.println(i1 == i2); // returns false
请参阅链接的一些附加信息
Answer 8:
根据JLS-5.1.7
If the value p being boxed is true, false, a byte, or a char in the range \u0000 to \u007f,
or an int or short number between -128 and 127 (inclusive), then let r1 and r2
be the results of any two boxing conversions of p. It is always the case that r1 == r2.
因此,-128和127之间的任意数字是基于整数级缓存。
请记住,比较两个对象时总是使用equals
方法。
缓存代码被写入IntegerCache
类,这是的构件Integer
类。
以下是代码片段:
/**
* Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
参考
- JLS-5.1.7
- Integer类代码
- 整数Java文档
文章来源: Using == operator in Java to compare wrapper objects