浅浅和平等有什么区别?这是如何应用于缓存的?

时间:2011-04-18 13:27:15

标签: java caching deep-copy shallow-copy

在我的笔记中找到以下内容,但我无法理解它:

  

原始类型包装类实现有限数量的缓存   价值观   这保证了有限数量的深度相等的包装器对象   也非常平等:   如果o1.equals( o2 )o1 == o2   例如,new Integer( 0 ) == new Integer( 0 )
  一般来说,这并不总是有效   例如,new Integer(666)== new Integer(666)
  可能不会举行   缓存的原因是它可以节省内存   通常,缓存适用于“小”原始值。

我不明白这是什么意思,或深(.equals())和浅(==)等于之间的区别。我知道在实践中,.equals必须用于对象,==用于Integral值,但实际的推理可能会让我感到不适。

我假设名称浅浅可能只检查两个值是否具有相同的类型和名称,哪些深度检查两个变量是否指向同一个对象?我不知道缓存会如何在这里发挥作用,或者为什么它会有用。

5 个答案:

答案 0 :(得分:6)

执行==时,您正在比较相等的参考。这意味着你说“两个对象的内存地址是否相同?”

执行.equals()时,您要比较对象本身是否相等。这意味着你说“这两个对象认为自己是平等的吗?”

给出的例子很差。 对JLS强制要求的这些数字进行的唯一缓存是.valueOf()方法。构造函数未缓存。

此外,JLS仅指定必须缓存的最小 [-128:127]。如果他们愿意,JVM实现可以缓存更多。这意味着Integer.valueOf(500) == Integer.valueOf(500)可能在某些计算机上为false,但在其他计算机上为true

class biziclop {

    public static void main(String[] args) {
        System.out.println(new Integer(5) == new Integer(5));
        System.out.println(new Integer(500) == new Integer(500));

        System.out.println(Integer.valueOf(5) == Integer.valueOf(5));
        System.out.println(Integer.valueOf(500) == Integer.valueOf(500));
    }
}

结果:

C:\Documents and Settings\glow\My Documents>java biziclop
false
false
true
false

C:\Documents and Settings\glow\My Documents>

在这里查看更详细的答案(评论是宝石!):Why do people still use primitive types in Java?

答案 1 :(得分:6)

嗯,实际上浅/深解剖不同于== /同等解剖:

  1. ==比较对象标识,即检查是否 操作数实际上是相同的 (两个引用相同的内存区域), 而equals比较对象 等价,即“逻辑”价值 两个,可能不完全相同 对象,是一样的。如果是两个 对象

    a == b
    

    然后确实

    a.equals(b) // if a != null
    

    ,但总的来说并非如此 例。

  2. 浅/深的区分是有道理的 仅用于equals比较。 浅意味着您只进行比较 两个对象的直接内容 找出他们是否“平等” 感觉,而深意味着你 比较对象的内容 递归直到所有你需要的 比较是原始字段。如果 你定义了你的equals方法 对象作为调用序列 equals在这些实例字段上 对象,你使用深度比较。如果 您使用equals定义== 运算符来比较复合类型, 比如字符串,那么你使用浅层比较 - 这在Java中是不正确的。
  3. 所有这一切的问题是,你绝不能使用==来比较两个复合对象,除非你认为它们是相同的,只有它们是相同的。

答案 2 :(得分:2)

首先关闭:new Integer(0) == new Integer(0) 从不评估为true,因为new 始终创建新对象,回避任何自动装箱 - 可能存在的缓存机制。

您可能听说过的是自动装箱(即在必要时自动将原始值转换为各自的包装类)。 Autoboxing使用的机制也可以使用包装类valueOf()方法访问。换句话说:将int自动装箱到Integer与调用Integer.valueOf(int)几乎相同。

Integer.valueOf(0) == Integer.valueOf(0) 评估为true,因为缓存了常用值(即绝对值较低的值)。当您连续两次致电Integer时,您将获得相同的 valueOf(0)对象。对于较高的值(例如示例中的666),这不一定正确。

答案 3 :(得分:1)

equals()测试两个对象是否基本相同,但它可以为两个不同的对象返回true;即,两个不同的纸夹是“等于”。对于引用类型,“==”测试两个引用是否引用相同的对象 - 即,纸夹= =仅对其自身。 ==测试身份equals测试等价

你可以有两个不同的Integer对象,其中包含0(它们是equals());缓存意味着保存对象并尽可能重用它们。

答案 4 :(得分:0)

你所谓的“浅等于”是身份:如果它们是完全相同的实例,则两个引用(即对象)是相同的。如果您知道其他语言中的指针,则可以将标识与指针相等进行比较。

你称之为“深度平等”的是平等:如果a返回b,则两个对象a.equals(b)true相等(并且希望如此反之亦然)。平等的正确性很大程度上取决于equals方法的实现方式。有关更多详细信息,请参阅Object类的Javadoc。