桥接方法是 JDK1.5
引入泛型后,为了使泛型方法生成的字节码与之前版本的字节码兼容,由编译器自动生成的方法。
通过代码可以更好地理解:
声明一个泛型接口
public interface A<T> {
void test(T t);
}
使用 String
类型实现一个具体的实现类
public class B implements A<String> {
public void test(String s) {
System.out.println(s);
}
}
泛型本身是语言级别的,经过编译后,泛型就会被擦除,所以接口 A
在编译后,test
方法的入参会被转换为 Object
public interface A {
void test(Object t);
}
实现类 B
中的实现方法是 void test(String s)
,其实根本就没有实现 void test(Object t)
方法。但是这个代码是正确的,可以正常运行,因为 JVM
在编译过程中对我们的实现类做了一点手脚
public class B implements A {
public void test(String s) {
System.out.println(s);
}
public void test(Object s) {
this.test((String) s);
}
}
编译后的类 B
也擦除了泛型,但是增加了一个方法同名的 test
方法,这个方法是代码中没有的,由 JVM
在编译期生成,是接口 A
中 test
方法的真正实现方法,这个方法就叫做桥接方法。
通过反射验证一下
public class Test {
public static void main(String[] args) {
Class<B> classB = B.class;
Method[] methods = classB.getDeclaredMethods();
System.out.println("方法总数量:" + methods.length);
for (Method method : methods) {
System.out.println(method.getReturnType().getSimpleName() + " "
+ method.getName() +
"(" + method.getParameters()[0].getType().getSimpleName() + ")"
+ " is " + (method.isBridge() ? "bridge" : "common") + " method"
);
}
}
}
输出如下
方法总数量:2
void test(String) is common method
void test(Object) is bridge method
一般项目中泛型的使用都是非常频繁的,使用反射进行一些公共逻辑处理时,突然遇到一个代码中没有的方法时,不要慌张,因为那可能是一个桥接方法。