如果我在这里遗漏了一些核心Java,请原谅我.
我正在通过HashSetjavadocs 搜索它的实现规范,它Collection.containsAll()显然继承了AbstractCollection根据JDK 8源代码文档的实现,如下所示:
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
我的问题源于这样一个事实:虽然HashSet不覆盖containsAll()它但是会覆盖contains():
public boolean contains(Object o) {
return map.containsKey(o);
}
Run Code Online (Sandbox Code Playgroud)
AbstractCollection 同样:
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o==null) {
while (it.hasNext())
if (it.next()==null)
return true;
} else {
while (it.hasNext())
if (o.equals(it.next()))
return true;
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
我的理解一直是当一个实例成员调用不明确实例中指定时,JVM隐含代替它this.instanceMemberCall(),在这种情况下,将转化成AbstractCollection的contains()被调用.但是,有一次我读到这里,对于时间复杂度HashMap/ HashSet的containsAll()是O(n)的暗示HashSet的contains()(O(1))被调用.将会明白这背后的实际语义是什么.
不,这只是多态性。每当在对象上调用方法时,该对象的真实类型都很重要,其他的都不重要。
含义:在 Base 中实现并不重要foo()。当foo()调用bar()被bar()Child 覆盖时。bar()当您有一个 Child 对象时,调用的将始终是 Child版本。
在您的示例中,this不是 AbstractSet,而是HashSet!
或者换句话说:在“何处”调用方法并不重要。重要的是调用它的对象的类型。如前所述,您的对象是 HashSet 类型!