java - 使用 new 运算符在 Java 中进行整数缓存

标签 java instance equals

在下面的类中,我尝试将包装类与原语进行比较,但结果不同。

我检查了以下链接 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.

如果有一个新对象,那么 ac 如何相等?

如果 b 等于 cc 等于 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
    }
}

更新: 通过引用这个链接Integer 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 vs int== 时,它需要将 Integer 转换为 int。这称为拆箱

JLS§5.1.8 :

If r is a reference of type Integer, then unboxing conversion converts r into r.intValue()

此时,您正在比较 intint。原语没有实例的概念,它们都引用相同的值。因此,结果为 true

所以你拥有的实际代码是

a.intValue() == c

导致比较 10 == 10,两个 int 值,不再有 Integer 实例。

当您比较 IntegerInteger 时,您可以看到 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 的缓存(参见 JLS§5.1.7)。

关于java - 使用 new 运算符在 Java 中进行整数缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56016969/

相关文章:

java - 哪个版本的jetty与cometd-3.0.2兼容

java - 使用 Java WatchService 监视文件夹中的文件夹

有界通配符的 Java 泛型行为

java - 如何实例化泛型类型?

php - 我如何在 PHP 中访问类实例的父级?

java - 使用 Java 和 EclipseLink 实现状态模式

java - 将实例变量与对象结合使用

Java HashMap/Hashtable 不检索自己的键

c# - Equals 方法在调试和 Release模式下的行为不同

java - Java 的 IndexOf 方法