当这个问题困扰我时,我正在阅读关于收藏的内容。
以下是我编写的代码来测试我的怀疑。
public static void main(String[] args) {
TreeMap<Integer, String> tree = new TreeMap<Integer, String>();
tree.put(1, "1");
tree.put(2, "2");
Set<Integer> set = tree.keySet();
System.out.println(set instanceof Set);
System.out.println(set instanceof HashSet);
}
结果:
真 假
上面的代码说我的set对象是Set的一个实例。但Set是一个接口如何实例化。我糊涂了。 :(
答案 0 :(得分:2)
Set
是一个接口,所以不,你不能直接实例化它。如果你不能拥有一个实例,那么接口将毫无用处! tree.keySet()
返回的实例是Set
接口的一些具体实现。
让我们得到超级具体,看看the TreeMap#keySet()
source code:
public Set<K> keySet() {
return navigableKeySet();
}
好的,这并没有告诉我们多少。我们需要向下钻取:
public NavigableSet<K> navigableKeySet() {
KeySet<K> nks = navigableKeySet;
return (nks != null) ? nks : (navigableKeySet = new KeySet(this));
}
所以返回的具体类型是KeySet
!你有Set
接口的实现。 http://www.docjar.com/html/api/java/util/TreeMap.java.html#1021
这解释了这个:
System.out.println(set instanceof Set); // prints true
System.out.println(set instanceof HashSet); // prints false
Set
是一个界面; HashSet
是该接口的实现。对于任何 foo instanceof Set
实施的每个实例true
,foo
将为Set
。我们已经确定TreeMap#keySet()
返回的对象的具体类型是KeySet
,而不是HashSet
,因此这解释了set instanceof HashSet
为false
的原因 - 因为set
是KeySet
,因此不能是HashSet
!
如果这仍然没有意义,read up on instanceof
:
instanceof
运算符将对象与指定类型进行比较。您可以使用它来测试对象是否是类的实例,子类的实例或实现特定接口的类的实例。