1

当这个问题困扰着我时,我正在阅读有关 Collections 的内容。

以下是我为测试我的疑问而编写的代码。

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 是一个 Interface 如何实例化它。我很困惑。:(

4

1 回答 1

2

Set是一个接口,所以不,你不能直接实例化它。但是,如果您不能拥有一个接口的实例,那么接口将毫无用处!返回的实例是接口tree.keySet()的一些具体实现Set

让我们变得超级具体,TreeMap#keySet()看看源代码

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的每个实例。我们已经确定了返回的对象的具体类型是 a ,而不是 a ,所以这就解释了为什么是- 因为是 a ,所以它不可能是 a !foo SetTreeMap#keySet()KeySetHashSetset instanceof HashSetfalsesetKeySetHashSet

如果这对您仍然没有意义,请继续阅读instanceof

运算符将instanceof对象与指定类型进行比较。您可以使用它来测试对象是类的实例、子类的实例还是实现特定接口的类的实例。

于 2012-12-01T04:13:22.463 回答