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

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

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

我不明白这是什么意思,或深(.equals())和浅(==)等于之间的区别。 我知道在实践中,.equals必须用于对象,而==用于Integral值,但实际的推理却暗示了我。

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

当你这样做==你正在比较参考是否相等。 这意味着你说“两个对象的内存地址是否相同?”

当你执行.equals()你正在比较Objects本身的相等性。 这意味着你说“这两个对象认为自己是平等的吗?”

给出的例子很差。 对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> 

在这里查看更详细的答案(评论是gem!): 为什么人们仍然在Java中使用原始类型?

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

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

     a == b 

    那是真的

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

    但在所有情况下都不一样。

  2. 浅/深的区分只对equals比较有意义。 浅意味着您只比较两个对象的直接内容以查找它们在您的意义上是否“相等”,而深意味着您递归地比较对象的内容,直到您需要比较的是原始字段。 如果将对象的equals方法定义为对这些对象的实例字段的equals调用序列,则使用深度比较。 如果使用==运算符定义equals比较复合类型(如字符串),则使用浅层比较 – 这在Java中是不正确的。

所有这一切的士气是你必须永远不要使用==来比较两个复合对象,除非你认为只有它们是相同的才相同。

首先关闭: new Integer(0) == new Integer(0) 永远不会计算为true ,因为new 总是创建一个新对象,回避可能存在的任何autoboxing-caching机制。

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

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

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

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

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

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