桥接方法是Java编译器为解决泛型擦除与多态冲突自动生成的合成方法,具有ACC_BRIDGE标志,用于确保子类方法能正确重写父类泛型方法。

桥接方法(Bridge Method)是 Java 编译器为解决泛型类型擦除与多态性冲突而自动生成的合成方法。它不显式出现在源码中,却真实存在于字节码里,对理解泛型、继承、重写机制至关重要。直接看源码无法察觉它的存在,必须借助 javap 反编译观察字节码才能确认。
什么是桥接方法?为什么需要它?
Java 泛型在编译期被擦除,但 JVM 要求方法签名(名称 + 参数类型 + 返回类型)必须严格匹配才能构成重写关系。当子类泛型类型更具体时,编译器会插入桥接方法来“补全”重写链。
例如:
- 父类定义
void process(List<object> list)</object> - 子类想重写为
void process(List<string> list)</string> - 擦除后两者都变成
process(List),看似可重写,但 JVM 实际只认签名一致——而返回类型不同(如协变返回)或参数类型擦除后不完全对应时,就必须靠桥接方法兜底。
用 javap 观察桥接方法的实操步骤
编写一个典型泛型继承示例(如 ArrayList<string></string> 继承 AbstractList<e></e>),然后执行:
立即学习“Java免费学习笔记(深入)”;
-
javac YourClass.java编译 -
javap -c -v YourClass查看详细字节码(-c显示指令,-v显示全部信息,含合成标志) - 重点查找带有
ACC_BRIDGE和ACC_SYNTHETIC标志的方法
你会看到类似这样的方法声明:
public java.lang.Object get(int);descriptor: (I)Ljava/lang/Object;
flags: (0x0041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC
这正是编译器为 String get(int) 自动生成的桥接方法,用于满足 AbstractList.get() 的原始签名要求。
桥接方法的关键特征与识别技巧
在 javap 输出中,桥接方法有三个明显标记:
-
方法名和参数与父类方法一致,但实际逻辑委托给子类的真实方法(如调用
areturn指令返回String,再由桥接方法自动转型为Object) -
字节码 flags 中包含
ACC_BRIDGE—— 这是最权威的识别依据,JVM 用它区分是否为桥接方法 -
不带源码行号(LineNumberTable 缺失或指向 0),且常标注
Synthetic,说明它由编译器生成,非人工编写
常见误区与调试建议
桥接方法容易被误认为“冗余代码”或“编译 bug”,其实它是泛型安全运行的必要桥梁:
- 反射调用时,
getDeclaredMethods()默认不返回桥接方法,需显式设置setAccessible(true)并过滤isBridge() - 使用 Lombok 或其他注解处理器时,可能叠加生成更多桥接方法,注意
javap输出中的重复签名 - 若发现本该重写却报
Override incompatible return type,很可能是缺少桥接方法支持,检查泛型边界和继承结构是否合理



















