Bridge Method是编译器为解决泛型擦除导致的多态断裂而生成的桥接方法,它用擦除后签名(如Object get())转发调用子类具体类型方法(如String get()),确保JVM多态正确性。

Bridge Method 是编译器为修复多态断裂而自动生成的“适配器”
泛型擦除后,父类方法签名被替换成原始类型(比如 T → Object),但子类若重写该方法并指定具体类型(如 String),就会出现 JVM 方法签名不匹配:父类是 Object get(),子类却是 String get()。JVM 不允许仅靠返回值不同来重载,更不允许这样覆盖——桥接方法就是编译器悄悄补上的那个“转发桩”,它用擦除后的签名(Object get())调用子类真正的 String get(),让多态能走通。
怎么看一个类有没有生成 Bridge Method?
用 javap -c -v 查看字节码,关注两点:
- 方法名相同、但签名含
bridge标志(ACC_BRIDGE和ACC_SYNTHETIC同时存在) - 方法体里只有一行
aload_0+invokespecial,指向你写的那个真实方法
例如:子类 StringBox extends Box<string></string> 重写了 get(),字节码中会出现一个 public bridge synthetic Object get() 方法,内部调用 String get()。
Bridge Method 不影响运行时性能,但会干扰反射和某些框架逻辑
桥接方法在运行时是真实存在的方法,只是被标记为合成(ACC_SYNTHETIC)。问题常出现在:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
立即学习“Java免费学习笔记(深入)”;
-
Class.getDeclaredMethods()会返回桥接方法,需用Method.isBridge()过滤 - Spring AOP 或 MyBatis 等基于反射代理的框架,若未跳过桥接方法,可能重复织入或匹配错误方法
- 手动遍历方法做泛型类型推导时(如解析
get()的返回泛型),桥接方法的签名已无泛型信息,必须跳过它,去找它委托的真实方法
为什么不能靠泛型保留类型直接解决?
因为 JVM 层面根本不认识泛型——从 Java 5 引入泛型起,就定死了“擦除优先”原则。所有泛型类在运行时都退化为原始类型(List<String>.class == List.class),所以无法靠运行时类型做分派。桥接方法不是设计选择,而是类型擦除与 JVM 方法分派机制冲突后,编译器唯一能做的妥协:用空间(多一个方法)换语义正确性(多态不崩)。
真正容易被忽略的是:桥接方法只出现在继承/实现泛型类型且重写泛型方法的场景;纯泛型类自身(如 ArrayList<T>)不会因泛型而生成桥接方法,只有当它被继承并重写 get() 这类方法时才会触发。

















