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

Java 继承体系中的类型擦除,核心在于:**泛型信息只在编译期存在,子类继承泛型父类时,实际擦除后的字节码中不保留具体类型参数,而是按边界(如 Object 或 Number)统一处理**。这直接影响方法签名、重写行为和反射获取能力。
泛型父类被擦除后,子类“看到”的是原始类型
比如父类定义为 class Container,无论子类写成 class StringContainer extends Container 还是 class IntContainer extends Container,编译后 JVM 加载的父类字节码里都只有:
private Object data;public Object get() { return data; }
子类继承的不是 Container,而是擦除后的 Container 原始类型。因此子类重写 get() 方法时,返回值也必须是 Object(或其子类),不能直接声明为 String —— 否则会破坏二进制兼容性。
桥接方法让多态“看起来正常”
当你在子类中写:
class StringContainer extends Container<string> {<br> @Override<br> public String get() { return (String) super.get(); }<br>}</string>
编译器会自动生成一个**桥接方法(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,那么擦除后所有成员字段、方法参数和返回值都会变成 Number,而非 Object。
子类继承 NumberContainer 后,重写方法的返回类型可以是 Integer(因为 Integer 是 Number 的子类),编译器仍能生成合法桥接方法。
但若父类无上界(),子类就无法安全返回更具体的类型,除非显式强转。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











