有人可以告诉我为什么这会返回真的吗?
我想如果我把东西投入到例如Object
,然后致电.equals
,
将使用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));
答案 0 :(得分:5)
因为这正是Javadocs所说的:
public boolean equals(Object o)
将指定对象与此set进行相等性比较。如果给定对象也是一个集合,则返回true,两个集合具有相同的大小,并且给定集合的每个成员都包含在此集合中。这可以确保equals方法在Set接口的不同实现中正常工作。
仅仅因为你把它投射到Object
并没有改变它实际上是什么。使用了equals()
中的覆盖HashSet
方法。
答案 1 :(得分:4)
默认情况下,Java中的方法是虚拟的。特别是,Object.equals
是虚拟的(因为它未被声明为final
)。从HashSet
overrides Object.equals
1 开始,您将看到在运行时类型为{{0}的对象上调用虚方法时使用的HashSet
equals
实现1}}(记住dynamic dispatch取决于接收对象的 runtime 类型,而不是编译时类型。)
1 :我们知道HashSet
会覆盖HashSet
,因为documentation表示Object.equals
来自HashSet
和文档对AbstractSet.equals
说:
将指定对象与此集进行相等性比较。如果指定的对象也是一个集合,则返回
AbstractSet
,两个集合具有相同的大小,并且指定集合的每个成员都包含在此集合中(或者等效地,此集合的每个成员都包含在指定的集合中) )。此定义确保equals方法在set接口的不同实现中正常工作。
明确定义值相等,而默认true
身份相等。
答案 2 :(得分:2)
因为多态性。
在运行时,实际的对象类型决定了实例方法的哪个实现应该执行。由于HashSet
继承了AbstractSet
的重写实现,因此用于比较Object.equals()
而且,AbstractSet#equals()州的JavaDocs
如果给定对象也是一个集合,则返回true,两个集合具有相同的大小,并且给定集合的每个成员都包含在此集合中。
因此,您的相等测试打印 true 。
因此,引用的类型(在您的情况下为 Object )与在运行时调用哪个版本的equals()
几乎没有关系。它完全取决于您的引用所指向的对象的类型。
答案 3 :(得分:1)
是的,equals的默认实现应该返回false。但是这里没有调用默认实现。对象类由java中的每个类型扩展,包括HashSet。
现在,如果您看到,您将使用Object类引用引用HashSet对象。因此调用HashSet equals。因此它返回true。