使用新运算符在Java中进行整数缓存

Use*_*345 23 java equals instance

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

我检查了以下链接链接

更为有趣的问题是,为什么new Object();每次都需要创建一个唯一实例?即为什么new Object();不允许缓存?答案是wait(...)notify(...)。缓存new Object()会错误地导致线程在不应该同步时彼此同步。

如果有一个新的对象,然后是如何ac平等的吗?

如果b等于cc等于aa则应等于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
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:通过引用此链接Integer caching

基本上,Integer类会将Integer实例的缓存保留在-128到127的范围内,并且所有自动装箱,文字和Integer.valueOf()的使用都会从该缓存返回其覆盖范围内的实例。

因此,在这种情况下,所有语句都应为真。

Zab*_*uza 27

说明

与进行Integer比较int==,需要将转换Integerint。这称为拆箱

参见JLS§5.1.8

如果r是type的引用Integer,则拆箱转换将转换rr.intValue()

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

所以实际的代码是

a.intValue() == c
Run Code Online (Sandbox Code Playgroud)

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

你可以看到,new Integer(...)确实创造了新的情况下,当你比较IntegerVS Integer。您在中做到了a == b


注意

构造函数new Integer(...)弃用。您应该改用Integer#valueOf,它可能会更快,并且还使用内部缓存。从文档中

返回Integer表示指定int值的实例。如果不需要新的Integer实例,则通常应优先于构造方法使用Integer(int)此方法,因为此方法通过缓存频繁请求的值可能会产生明显更好的空间和时间性能。此方法将总是在范围内的缓存值到,包容性,并可以缓存其他值在该范围之外。-128127

缓存在这里要特别注意,因为它==会再次变为真(对于缓存的值):

Integer first = Integer.valueOf(10);
Integer second = Integer.valueOf(10);
System.out.println(first == second); // true
Run Code Online (Sandbox Code Playgroud)

对于-128和之间的值+127,可以保证缓存,但也可以将其用于其他值。

另请注意,您b实际上是从缓存中出来的,因为

Integer b = 10;
// same as
Integer b = Integer.valueOf(10);
// and not
Integer b = new Integer(10);
Run Code Online (Sandbox Code Playgroud)

因此,装箱经过Integers缓存(请参阅JLS§5.1.7)。

  • “更快”是一个过分的主张。正如文档所述,“此方法*可能*可以显着改善空间和时间性能”,换言之,它使潜在的优化(无论是否存在)取决于实现。 (2认同)