3

有人能告诉我为什么这会返回 true 吗?我想如果我将某些东西转换为 egObject然后调用.equals,将使用默认实现 from Object。并且 s1 == s2 应该返回 false。

请告诉我在哪个主题下可以找到有关此行为的更多信息。

   Set<String> s1 = new HashSet<String>(as("a"));
   Set<String> s2 = new HashSet<String>(as("a"));

   Object o1 = (Object)s1;
   Object o2 = (Object)s2;

   System.out.println(o1.equals(o2));
4

4 回答 4

5

因为这正是Javadocs所说的:

public boolean equals(Object o)
比较指定的对象和这个集合是否相等。如果给定对象也是一个集合,则返回 true,这两个集合具有相同的大小,并且给定集合的每个成员都包含在该集合中。这确保了 equals 方法在 Set 接口的不同实现中正常工作。

仅仅因为您将其转换为Object并不会改变它的实际情况。使用了覆盖的equals()方法HashSet

于 2013-06-29T18:06:51.847 回答
4

Java 中的方法默认是虚拟的。特别是,Object.equals是虚拟的(因为它没有声明final)。由于HashSet覆盖Object.equals1 ,当您在具有运行时类型的对象上调用虚拟方法时,您将看到 used 的HashSet实现(请记住,动态调度取决于接收对象的运行时类型,而不是编译时类型)。equalsHashSet

1:我们知道HashSet覆盖Object.equals是因为文档HashSet源自AbstractSet并且文档AbstractSet.equals 说:

比较指定对象与此集合是否相等。true如果指定对象也是一个集合,则返回两个集合的大小相同,并且指定集合的​​每个成员都包含在此集合中(或等效地,此集合的每个成员都包含在指定集合中)。此定义确保 equals 方法在 set 接口的不同实现中正常工作。

它清楚地定义了相等,而默认值Object.equals身份相等。

于 2013-06-29T18:09:34.590 回答
2

因为,多态性

在运行时,对象的实际类型决定了实例方法的哪个实现应该执行。因为,从它HashSet继承了一个被覆盖的实现,AbstractSet用于比较而不是Object.equals()

并且,AbstractSet#equals()状态的 JavaDocs

如果给定对象也是一个集合,则返回 true,这两个集合具有相同的大小,并且给定集合的每个成员都包含在该集合中。

因此,您的平等测试打印true

因此,引用的类型(在您的情况下为Objectequals() )与在运行时调用的哪个版本几乎没有关系。这完全取决于您的引用指向的对象的类型。

于 2013-06-29T18:06:22.120 回答
1

是的,equals 的默认实现应该返回 false。但是这里没有调用默认实现。对象类由java中的everytype扩展,包括HashSet。

现在,如果您看到,您指的是带有 Object 类引用的 HashSet 对象。因此 HashSet equals 被调用。因此它返回true。

于 2013-06-29T18:07:54.807 回答