我无法解释为什么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,可能需要保留规则以便向后兼容(存在遗留类,隐式声明静态嵌套接口,如果规则被改变,会突然变得非静态)。为了优化我的问题,此规则是仅是为了向后兼容,还是有一个我缺失的固有原因?