自限定泛型 class node 的核心是强制子类自我绑定,确保类型参数 t 必须是当前类或其子类,从而避免方法重载错误、保障链式调用返回精确子类型,并在编译期拒绝非法继承(如 node)。

这个写法 class Node<t extends node>></t> 看起来绕,但核心就一点:让泛型参数 T 必须是当前类(或其子类)的类型本身,从而在继承链中“锁住”类型一致性。
它不是循环定义,而是类型契约
表面上看,Node 还没定义完,就在边界里用上了自己——这确实违反直觉。但 Java 编译器允许这种写法,因为它不依赖运行时结构,只做编译期类型检查。关键在于:这个 extends 不是说 “T 是 Node 的子类”,而是声明 “T 必须满足:T 继承自 Node<t></t>”。换句话说,只有像 class A extends Node<a></a> 这样的类才合法。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
为什么需要这样写?解决什么问题?
-
避免父类方法被意外重载:比如普通基类
Node定义了set(Node n),子类RedNode想重写为set(RedNode r),结果只是重载而非覆盖——调用时可能走错方法。而用自限定后,父类方法签名自动变成set(T t),子类继承后T就是RedNode,天然就是类型精准的方法。 -
保证链式操作的类型安全:比如
node.set(...).get()返回的永远是子类自身类型,不会退化成父类或Object。 -
强制子类“自我绑定”:编译器会拒绝
class Bad extends Node<string></string>这种写法,因为String并不继承Node<string></string>—— 这正是自限定的约束力所在。
典型用法示例
常见于树节点、构建器、可链式调用的 API:
class TreeNode<t extends treenode>> {
T parent;
List<t> children = new ArrayList();
T setParent(T p) {
this.parent = p;
return (T) this; // 安全返回子类实例
}
}
class BinaryNode extends TreeNode<binarynode> { } // ✅ 合法
// class InvalidNode extends TreeNode<string> { } // ❌ 编译失败</string></binarynode></t></t>
注意一个常见误解
有人以为 T extends Node<t></t> 允许 class B extends Node<a></a>(即 T 是另一个类),但实际上不行——除非 A 本身也满足 A extends Node<a></a>,否则编译通不过。自限定真正生效的地方,是在子类声明时对自身类型的显式绑定,而不是泛型参数的任意替换。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










