Java泛型继承要求子类必须显式或隐式绑定父类类型参数,否则编译报错或擦除为Object;子类可固定类型、延续泛型、引入新参数,但不可省略声明或使用通配符。

Java 中泛型父类与子类继承时,类型参数的传递关键在于明确“谁声明、谁绑定、谁使用”。核心原则是:子类必须显式或隐式地为父类的类型参数提供具体类型(或继续泛化),否则编译器无法推断,会报错或擦除为 Object。
子类直接指定具体类型(最常见)
当子类不泛化父类的类型参数,而是固定使用某个具体类型时,需在继承语句中直接传入实参。
- 父类定义:
class Box<T> { T value; void set(T t) { value = t; } } - 子类绑定:
class StringBox extends Box<String> { }—— 此时StringBox继承的是已具体化的Box<String>,所有T都被替换为String - 效果:子类方法签名中不再含
T,set()变成set(String),类型安全由编译器保证
子类延续泛型并复用父类类型参数
若子类也要支持泛型,且希望与父类类型参数保持一致或扩展关系,应声明自己的类型参数,并将其传递给父类。
- 正确写法:
class GenericBox<T> extends Box<T> { }—— 子类声明<T>,再传给Box<T> - 也可重命名或约束:
class NumberBox<N extends Number> extends Box<N> { },此时N必须是Number或其子类 - 注意:不能省略子类的类型声明,如
class BadBox extends Box<T>是非法的——T未定义
子类引入新类型参数并组合使用
子类可声明多个类型参数,将其中一部分传递给父类,另一部分用于自身逻辑。
立即学习“Java免费学习笔记(深入)”;
- 例如:
class PairBox<K, V> extends Box<Pair<K, V>> { }—— 父类类型参数是Pair<K,V>,而K和V是子类新引入的 - 也可混合绑定:
class IntKeyBox<V> extends Box<Pair<Integer, V>> { },固定K为Integer,泛化V - 关键点:父类所需的具体类型必须能由子类当前上下文完全确定,不能依赖未声明的符号
避免常见错误
很多问题源于类型擦除和声明缺失,而非语法错误。
-
不要写
class Child extends Parent<?>—— 这是通配符,表示“某个未知类型”,不能用于继承(仅适用于变量/参数) -
不要省略父类类型参数:
class Bad extends Box实际等价于Box<Object>(原始类型),丢失泛型信息,且子类无法访问原始T的真实类型 -
类型参数名无继承关系:父类用
T,子类用E完全合法,只要传递正确,名字本身不关联


















