为什么Java中的嵌套接口不是静态的?

时间:2018-02-13 22:00:26

标签: java generics nested

我无法解释为什么Java不允许非静态嵌套接口。它对嵌套类型和泛型之间的交互产生了影响,因为非静态嵌套类型将从其封闭类型隐式通用。下面使用嵌套接口作为两个嵌套类的超类型,在我看来是合理使用非静态嵌套接口:

public class BSTMap0<K extends Comparable<K>, V> {

    private interface Node {
        Node put(K key, V value);
        V get(K key);
    }

    private class NullNode implements Node {
        public Node put(K key, V value) {
            return new RealNode(key, value, this, this);
        }
        public V get(K key) { return null; }
    }

    private class RealNode implements Node {
        // details omitted
    }
    private Node root;
    public BSTMap0() { root = new NullNode(); }
    public void put(K key, V value) { root = root.put(key, value); }
    public V get(K key) { return root.get(key); }
}

这不是合法的Java,因为Node接口是隐式静态的,因此不是隐式通用的。有两种简单的解决方法。我们可以使接口明确通用:

public class BSTMap1<K extends Comparable<K>, V> {

    private interface Node<KK extends Comparable<KK>, VV> {
        Node<KK,VV> put(KK key, VV value);
        VV get(KK key);
    }
    private class NullNode implements Node<K, V> {
        public Node<K,V> put(K key, V value) {
            return new RealNode(key, value, this, this);
        }
        public V get(K key) { return null; }
    }
    // ... etc

这让我感到不必要的冗长和丑陋。或者,我们可以使接口成为一个抽象类,包含所有抽象方法:

public class BSTMap2<K extends Comparable<K>,V> {

    private abstract class Node {
        abstract Node put(K key, V value);
        abstract V get(K key);
    }

    private class NullNode extends Node {
        public Node put(K key, V value) {
            return new RealNode(key, value, this, this);
        }
        public V get(K key) { return null; }
    }
    // ... etc

我并不关心这一点,因为Node类型仅存在于多态,而不是实现继承,因此从概念上讲它是一个接口,而不是一个抽象类。

任何人都可以解释为什么Java不允许使用第一个版本,这对我来说似乎是正确的解决方案吗?几年前,here提出了一个类似的问题,但并未得到回答。我希望我给出的例子能更好地激发这个问题。

编辑:自发布以来,我意识到(以下评论也指出)此规则比Java中的泛型更旧。如果没有泛型,嵌套接口就不需要是非静态的,并且一旦将泛型引入Java,可能需要保留规则以便向后兼容(存在遗留类,隐式声明静态嵌套接口,如果规则被改变,会突然变得非静态)。为了优化我的问题,此规则是是为了向后兼容,还是有一个我缺失的固有原因?

0 个答案:

没有答案