橋接方法是 JDK 1.5 引入泛型后,為了使Java的泛型方法生成的字節碼和 1.5 版本前的字節碼相兼容,由編譯器自動生成的方法。我們可以通過Method.isBridge()方法來判斷一個方法是否是橋接方法。
假定接口
public interface SuperClass<T> { void method(T t); }
它的一個實現類
public class AClass implements SuperClass<String> { @Override public void method(String s) {
System.out.println(s);
}
}
因為泛型是在1.5引入的,為了向前兼容,所以會在編譯時去掉泛型(泛型擦除)。那么SuperClass接口中的method方法的參數在虛擬機中只能是Object。
它應該是這個樣子:
public interface SuperClass { void method(Object t); }
而 AClass 實現了SuperClass 接口,但是它的實現方法卻是:
public void method(String s) { System.out.println(s); }
根本就沒有實現 void method(Object t) 方法。 這怎么回事,其實虛擬機自動實現了一個方法。
AClass在虛擬機中是這個樣子:
public class AClass implements SuperClass { public void method(String s) { System.out.println(s); } public void method(Object s) { this.method((String) s); } }
這個void method(Object s) 就是橋接方法。
我們用這個命令查看
javap -p AClass.class
顯示如下:
Compiled from "AClass.java" public class AClass implements SuperClass<java.lang.String> { public AClass(); public void method(java.lang.String); public void method(java.lang.Object); }
我們用反射寫個測試,看結果如何
public static void main(String[] args) throws Exception { AClass obj = new AClass(); Method m = AClass.class.getMethod("method", String.class); m.invoke(obj, "XXXXXXXXXXXXXXXXXX"); System.out.println(m.isBridge()); m = AClass.class.getMethod("method", Object.class); m.invoke(obj, "##################"); System.out.println(m.isBridge()); }
測試結果如下
XXXXXXXXXXXXXXXXXX false ################## true