桥接方法的根本目的是在类型擦除后维持多态正确性,确保子类重写父类/接口泛型方法的行为能被JVM正确识别和分派;它通过生成签名匹配擦除后父类方法、内部强制转换并转发调用的合成方法来补全重写关系,标记为ACC_BRIDGE | ACC_SYNTHETIC。

编译器为泛型类中的方法自动生成 synthetic bridge(桥接)方法,根本目的是在类型擦除后维持多态的正确性——确保子类重写父类/接口泛型方法的行为,在运行时仍能被 JVM 正确识别和分派。
解决擦除导致的“重写失效”问题
Java 泛型仅存在于编译期,运行时所有泛型参数都被擦除。例如:
- 接口
Comparable<t></t>擦除后变成Comparable,其方法变为compareTo(Object) - 实现类
Integer implements Comparable<integer></integer>中实际定义的是compareTo(Integer)
JVM 判定重写只看方法签名(名称 + 参数类型 + 返回类型)。擦除后,compareTo(Object) 和 compareTo(Integer) 签名不同,JVM 认为它们不是重写关系。若无桥接方法,向上转型调用就会落到父类默认实现或报错,多态完全失效。
补全签名差异,让 JVM “看见”重写
编译器自动插入一个与父类擦除后签名完全一致的方法,内部只做类型转换并转发到子类真实方法:
- 签名匹配:参数为
Object,返回为int(对应擦除后的Comparable) - 行为一致:调用子类的
compareTo(Integer),并强转参数 - 标记明确:该方法带
ACC_BRIDGE | ACC_SYNTHETIC标志,表明它是编译器生成、非源码编写
覆盖协变返回类型场景
不仅参数类型变化会触发桥接,返回类型泛型擦除不一致同样需要:
- 父类
Box<t></t>中声明abstract T get();→ 擦除为Object get() - 子类
StringBox extends Box<string></string>实现String get() - JVM 不认为
String get()重写了Object get(),因为返回类型不同 - 编译器生成桥接方法:
public Object get() { return this.get(); },确保通过Box引用也能调用到子类逻辑
保障二进制兼容性与旧代码可运行
桥接方法使泛型代码生成的字节码,能被 JDK 1.5 之前就存在的 JVM 和类库直接使用。比如 TreeSet 内部调用 Comparable.compareTo(Object),无需关心传入对象是否是泛型实现类——只要它有正确的桥接方法,就能安全分派。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











