Java泛型多态靠桥接方法维持,编译器在类型擦除后自动生成bridge方法,将Object参数强转并委托给具体类型方法,确保父类引用调用时仍能正确执行子类逻辑。

Java 泛型的多态能正常工作,靠的不是泛型本身保留了类型信息,而是编译器在类型擦除后主动“补位”——用桥接方法把被擦掉的多态链条重新接上。
类型擦除让父子方法签名不匹配
泛型类定义的方法参数是 T,擦除后统一变成 Object;但子类重写时往往按具体类型(如 String)来写方法。这就导致:父类擦除后是 void set(Object),子类写的是 void set(String)。从 JVM 角度看,这俩不是重写关系,而是两个独立方法——多态失效。
常见后果包括:
- 通过父类引用调用方法时,可能意外走到父类实现,而非子类重写逻辑
- 运行时强转失败(比如往
Node<integer></integer>里塞字符串,触发ClassCastException) - 反射遍历时看到两个同名方法,其中一个是编译器生成的桥接方法
桥接方法是编译器自动生成的“适配器”
为修复签名断层,编译器悄悄在子类中插入一个桥接方法,它:
立即学习“Java免费学习笔记(深入)”;
- 方法名和返回值与父类擦除后一致(如
public void set(Object)) - 方法体只做一件事:把参数强转为目标类型,再委托给子类写的真正方法(如
set((String) obj)) - 被标记为
bridge和synthetic,源码里看不到,但Method#isBridge()能检测到
这样,当 Generic<string> ref = new StringGeneric(); ref.set("hi");</string> 执行时,JVM 查找 set(Object),命中桥接方法,再跳转到你写的 set(String),多态就稳了。
没有桥接方法,多态就不可靠
如果编译器不生成桥接方法,以下情况会出问题:
- 子类无法真正覆盖父类泛型方法,违反面向对象基本契约
- 使用原始类型(raw type)引用子类实例时,调用行为不可预测
- 框架(如 Spring、Jackson)依赖反射获取方法时,可能漏掉子类逻辑
桥接方法不是优化手段,而是类型擦除下维持 Java 多态语义的必要补偿机制。
你可以验证桥接方法的存在
用反射遍历子类声明的方法,检查 isBridge():
for (Method m : MyNode.class.getDeclaredMethods()) {
System.out.println(m.getName() + " → isBridge: " + m.isBridge());
}
通常会看到一对 setData:一个 setData(Integer)(你写的),一个 setData(Object)(桥接的,isBridge == true)。


















