最近我偶然发现了一个看起来不合逻辑的泛型的边缘情况。
我有一个简单的界面,它返回一个孩子的列表:
public interface INode<C extends INode> {
List<C> getChildren();
}
Run Code Online (Sandbox Code Playgroud)
我希望如果 INode 类型在没有定义 C 类型的情况下被引用,C 类型将被编译器推断为 INode。换句话说,在下面的代码中:
public void retrieveChildren(INode node) {
var children = node.getChildren();
}
Run Code Online (Sandbox Code Playgroud)
儿童将被推断为List<INode>类型。相反,它只是普通的 List。
值得注意的是,类型推断在 INode 方法返回单个元素的情况下按预期工作,因此当此接口时:
public interface INode<C extends INode> {
C getFirstChild();
}
Run Code Online (Sandbox Code Playgroud)
用于以下方法:
public void retrieveFirstChild(INode node) {
var firstChild = node.getFirstChild();
}
Run Code Online (Sandbox Code Playgroud)
firstChild 被正确地推断为 INode。
jdk 有这样工作的理由吗?另外,是否有一种干净的方法可以为返回的列表强制使用 C 类型?
非常感谢。