Java泛型继承中类型擦除指编译后泛型参数被替换为上界(如Object或Number),子类继承的是原始类型而非参数化类型,重写方法需匹配擦除后的签名,桥接方法保障多态调用,反射无法获取运行时泛型信息。

Java 继承体系中的类型擦除,核心在于:**泛型信息只在编译期存在,子类继承泛型父类时,实际擦除后的字节码中不保留具体类型参数,而是按边界(如 Object 或 Number)统一处理**。这直接影响方法签名、重写行为和反射获取能力。
泛型父类被擦除后,子类“看到”的是原始类型
比如父类定义为 class Container<t> { T data; T get() { return data; } }</t>,无论子类写成 class StringContainer extends Container<string></string> 还是 class IntContainer extends Container<integer></integer>,编译后 JVM 加载的父类字节码里都只有:
private Object data;public Object get() { return data; }
子类继承的不是 Container<string></string>,而是擦除后的 Container 原始类型。因此子类重写 get() 方法时,返回值也必须是 Object(或其子类),不能直接声明为 String —— 否则会破坏二进制兼容性。
桥接方法让多态“看起来正常”
当你在子类中写:
class StringContainer extends Container<String> {<br> @Override<br> public String get() { return (String) super.get(); }<br>}编译器会自动生成一个**桥接方法(bridge method)**:
public Object get() { return this.get(); }这个合成方法转发调用到你写的
String get(),确保父类引用能正确调用子类实现。它对开发者透明,但对 JVM 多态调用至关重要。
反射获取继承方法时,泛型类型已不可见
在 StringContainer 中调用 getClass().getDeclaredMethod("get"),返回的方法返回类型是 Object.class,不是 String.class;
即使尝试用 getGenericReturnType(),也只能从父类声明处(如 Container.class 的 get() 方法)拿到 java.lang.String 的泛型签名——但这是编译期保留的元数据,并非运行时真实类型。
上界会影响擦除结果,进而影响继承约束
若父类是 class NumberContainer<t extends number></t>,那么擦除后所有成员字段、方法参数和返回值都会变成 Number,而非 Object。
子类继承 NumberContainer<integer></integer> 后,重写方法的返回类型可以是 Integer(因为 Integer 是 Number 的子类),编译器仍能生成合法桥接方法。
但若父类无上界(<t></t>),子类就无法安全返回更具体的类型,除非显式强转。


















