桥接方法是Java编译器为解决类型擦除导致的签名不匹配而自动生成的辅助方法,确保泛型子类正确重写父类方法;其签名与父类擦除后一致,内部委托调用真实实现,并标记ACC_BRIDGE和ACC_SYNTHETIC。

Java 5 引入泛型时,采用类型擦除(Type Erasure)作为核心机制,桥接方法正是为弥补擦除后产生的签名不匹配问题而由编译器自动生成的——它不是运行时行为,而是编译期“补位”手段,确保子类重写泛型父类/接口方法后,JVM 仍能按旧版字节码规则正确分派调用。
类型擦除导致的方法签名断裂
泛型只存在于源码和编译前期,编译后所有类型参数被擦除:
-
SuperClass<String>中的abstract T get(T t)擦除为Object get(Object t) - 子类
SubClass显式实现String get(String s),擦除后变成String get(String s)
Object get(Object) 和 String get(String)。由于 Java 虚拟机方法重写依赖签名(方法名 + 参数类型),子类实际并未覆盖父类方法,导致多态失效、编译报错或运行时 AbstractMethodError。
桥接方法如何“缝合”签名断层
编译器在子类中自动插入一个桥接方法,其作用是:
- 方法名和参数类型与父类擦除后的签名完全一致(如
Object get(Object)) - 方法体仅做类型转换并委托给子类真实实现(如
return this.get((String) arg0);) - 字节码中标记
ACC_BRIDGE | ACC_SYNTHETIC,表明它是编译器生成、非源码编写
get(Object) 时,实际执行的是这个桥接方法,再跳转到子类的 String get(String),语义保持不变,且完全兼容 Java 1.4 的 invokevirtual 查找逻辑。
典型触发场景不只是继承泛型类
桥接方法在以下情况均由编译器静默生成:
- 实现泛型接口(如
interface Action<T> { T run(); }→ 实现类返回String run()) - 协变返回类型(子类重写方法返回更具体的子类型,如父类返回
Object,子类返回String) - 泛型类继承非泛型父类并重写擦除后签名冲突的方法
验证桥接方法的存在
可通过反射快速确认:
-
method.isBridge()返回true即为桥接方法 -
javap -v ClassName查看字节码,桥接方法会显示bridge和synthetic标志 - IDE 调试时方法列表中常出现同名但参数/返回值不同的“隐藏方法”,即桥接方法


















