Java中可通过递归泛型(T extends TreeNode<T>)定义类型安全的树形结构,使子节点与父节点类型一致,支持无限嵌套、编译期类型检查及免强制转换的遍历。

Java 中可以通过递归泛型(Recursive Generic Type)在泛型类中定义树形结构,核心是让类型参数约束自身为该泛型类型的子类型,从而支持任意深度嵌套的父子关系。
用递归泛型声明树节点
关键在于让泛型参数 T extends TreeNode<T>,表示当前节点类型必须是 TreeNode 的某种具体化,且能持有同类型的子节点。这样既保持类型安全,又允许无限层级嵌套:
- 定义抽象基类:abstract class TreeNode<T extends TreeNode<T>> {
- 声明子节点列表为 List<T> children;,而非 List<TreeNode<T>>,确保子节点与当前节点类型一致
- 提供通用方法如 addChild(T child)、getChildren(),返回值和参数都保持 T 类型
具体业务类继承并固化类型
实际使用时,需定义具体业务类(如 OrderNode、OrgNode),并显式指定递归泛型实参为自己:
- class OrderNode extends TreeNode<OrderNode> {
- 可在其中添加业务字段:订单号、金额、状态等
- 构造函数可初始化父节点引用、children 列表等基础设施
- 所有子节点也必须是 OrderNode,编译器会强制检查,避免混入其他类型
构建与遍历树时保持类型完整性
递归泛型不改变运行时行为,但提升编译期安全。构建和遍历时无需强制转换:
立即学习“Java免费学习笔记(深入)”;
- 创建树:OrderNode root = new OrderNode(); root.addChild(new OrderNode());
- 遍历子节点时,for (OrderNode child : root.getChildren()) 直接获得 OrderNode 类型
- 递归方法(如计算总金额)可直接声明为 BigDecimal calcTotal(OrderNode node),无需泛型通配或转型
注意边界与局限性
递归泛型写法简洁,但有几点需留意:
- 不能用于静态上下文(如静态字段或方法),因为类型参数在静态时不可知
- 泛型擦除后运行时无法区分不同递归实例,反射或序列化需额外处理
- 若需多态兼容(如统一处理多种树节点),可配合接口 + 递归泛型组合,例如 interface Treeable<T extends Treeable<T>>


















