桥接方法的核心作用是解决类型擦除导致的签名断裂,保障JVM多态调用正确性;它由编译器自动生成,签名与父类擦除后一致并转发至子类真实方法,支持返回值协变,但不恢复类型信息、不解决参数不兼容问题。

桥接方法的核心作用,是让子类对父类泛型方法的重写在字节码层面“看起来像真的重写了”,从而保障JVM能正确执行多态调用。
解决类型擦除导致的签名断裂
Java泛型在编译后会被擦除,比如 public T get() 变成 public Object get();而子类若写成 @Override public String get(),源码上看似重写成功,但擦除后父类方法签名为 Object get(),子类实际方法签名为 String get()——二者不一致,JVM认为这不是重写,而是重载,多态就会失效。
编译器此时自动生成一个桥接方法:
- 签名与父类擦除后完全一致:
public Object get() - 方法体只做一件事:
return this.get();(即调用子类真实的String get()) - 该方法被标记为
ACC_BRIDGE和ACC_SYNTHETIC,仅由编译器生成,不可见于源码
支撑运行时方法分派的准确性
JVM 方法调用依赖 descriptor(方法描述符),而非源码表面类型。没有桥接方法时:
- 通过父类引用调用
get(),JVM 查找的是Object get()签名 - 子类中只有
String get(),匹配失败 → 调用父类实现(或抛 AbstractMethodError)
有了桥接方法后:
- 子类字节码中同时存在
String get()和Object get()(桥接版) - JVM 按 descriptor 匹配到桥接方法,再由它转发到真实方法
- 外部代码无论用父类还是子类类型调用,最终都走到子类逻辑
覆盖返回值协变的底层机制
不只是泛型,任何返回类型更具体的重写(如父类返回 Number,子类返回 Integer)都会触发桥接方法生成:
- 父类:
public Number getValue() - 子类:
@Override public Integer getValue() - 桥接方法:
public Number getValue() { return this.getValue(); }
这说明桥接不是泛型专属,而是 JVM 对“返回类型协变”在字节码层的统一支持方案——它把语义上合理的重写,翻译成 JVM 能识别的签名等价形式。
桥接方法不是万能的,有明确边界
它只修复签名兼容性,不恢复类型信息:
- 反射拿到桥接方法的
getReturnType()是Object.class或Number.class,不是String.class或Integer.class - 若子类参数类型与父类擦除后不兼容(如父类
set(T)擦除为set(Object),子类却写set(Integer)),编译直接报错,不会生成桥接方法 - 桥接方法内部只是强制转型+转发,不提供额外类型安全,运行时异常仍可能发生

















