使用 new 运算符在 Java 中进行整数缓存
Integer caching in Java with new operator
在下面的 class 中,我尝试将包装器 class 与原语进行比较,但结果不同。
我检查了以下 links links:
The more interesting question is why new Object();
should be required to create a unique instance every time? i. e. why is new Object();
not allowed to cache? The answer is the wait(...)
and notify(...)
calls. Caching new Object()
s would incorrectly cause threads to synchronize with each other when they shouldn't.
如果有一个新对象,那么 a
和 c
怎么相等?
如果b
等于c
且c
等于a
,那么a
应该等于b
。但在以下情况下,我得到了 a != c
.
请说明。
class WrapperCompare {
public static void main (String args[]) {
Integer a = new Integer(10);
Integer b = 10;
int c=10;
System.out.println(b==c); //true
System.out.println(a==b); //false
System.out.println(a==c); //true
}
}
更新:
通过参考这个linkInteger caching。
Basically, the Integer class keeps a cache of Integer instances in the range of -128 to 127, and all autoboxing, literals and uses of Integer.valueOf() will return instances from that cache for the range it covers.
所以在这种情况下,所有陈述都应该是正确的。
说明
当您将 Integer
与 int
与 ==
进行比较时,它需要将 Integer
转换为 int
。这叫做拆箱。
If r
is a reference of type Integer
, then unboxing conversion converts r
into r.intValue()
此时,您正在比较 int
与 int
。基元没有实例的概念,它们都引用相同的值。因此,结果是 true
.
所以你的实际代码是
a.intValue() == c
导致比较 10 == 10
,两个 int
值,不再有 Integer
个实例。
当您比较 Integer
与 Integer
时,您可以看到 new Integer(...)
确实创建了新实例。你在 a == b
.
中做到了
备注
构造函数 new Integer(...)
已 弃用 。您应该改为使用 Integer#valueOf
,它可能更快并且还使用内部缓存。来自 documentation:
Returns an Integer
instance representing the specified int
value. If a new Integer instance is not required, this method should generally be used in preference to the constructor 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.
缓存在这里很重要,因为它会导致 ==
再次为真(对于缓存值):
Integer first = Integer.valueOf(10);
Integer second = Integer.valueOf(10);
System.out.println(first == second); // true
保证缓存 -128
和 +127
之间的值,但也可用于其他值。
另请注意,您的 b
实际上是从缓存中取出的,因为
Integer b = 10;
// same as
Integer b = Integer.valueOf(10);
// and not
Integer b = new Integer(10);
因此 boxing 通过 Integer
s 缓存(参见 JLS§5.1.7)。
在下面的 class 中,我尝试将包装器 class 与原语进行比较,但结果不同。
我检查了以下 links links:
The more interesting question is why
new Object();
should be required to create a unique instance every time? i. e. why isnew Object();
not allowed to cache? The answer is thewait(...)
andnotify(...)
calls. Caching newObject()
s would incorrectly cause threads to synchronize with each other when they shouldn't.
如果有一个新对象,那么 a
和 c
怎么相等?
如果b
等于c
且c
等于a
,那么a
应该等于b
。但在以下情况下,我得到了 a != c
.
请说明。
class WrapperCompare {
public static void main (String args[]) {
Integer a = new Integer(10);
Integer b = 10;
int c=10;
System.out.println(b==c); //true
System.out.println(a==b); //false
System.out.println(a==c); //true
}
}
更新: 通过参考这个linkInteger caching。
Basically, the Integer class keeps a cache of Integer instances in the range of -128 to 127, and all autoboxing, literals and uses of Integer.valueOf() will return instances from that cache for the range it covers.
所以在这种情况下,所有陈述都应该是正确的。
说明
当您将 Integer
与 int
与 ==
进行比较时,它需要将 Integer
转换为 int
。这叫做拆箱。
If
r
is a reference of typeInteger
, then unboxing conversion convertsr
intor.intValue()
此时,您正在比较 int
与 int
。基元没有实例的概念,它们都引用相同的值。因此,结果是 true
.
所以你的实际代码是
a.intValue() == c
导致比较 10 == 10
,两个 int
值,不再有 Integer
个实例。
当您比较 Integer
与 Integer
时,您可以看到 new Integer(...)
确实创建了新实例。你在 a == b
.
备注
构造函数 new Integer(...)
已 弃用 。您应该改为使用 Integer#valueOf
,它可能更快并且还使用内部缓存。来自 documentation:
Returns an
Integer
instance representing the specifiedint
value. If a new Integer instance is not required, this method should generally be used in preference to the constructorInteger(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
to127
, inclusive, and may cache other values outside of this range.
缓存在这里很重要,因为它会导致 ==
再次为真(对于缓存值):
Integer first = Integer.valueOf(10);
Integer second = Integer.valueOf(10);
System.out.println(first == second); // true
保证缓存 -128
和 +127
之间的值,但也可用于其他值。
另请注意,您的 b
实际上是从缓存中取出的,因为
Integer b = 10;
// same as
Integer b = Integer.valueOf(10);
// and not
Integer b = new Integer(10);
因此 boxing 通过 Integer
s 缓存(参见 JLS§5.1.7)。