在JDK 1.5 引入泛型后就引入了桥接方法,也可以理解为桥接方法是泛型的本质(载体)泛型只是表象。熟悉泛型的童靴可能都知道,Java泛型的处理几乎都在编译器中进行,编译器生成的bytecode是不包涵泛型信息的,泛型类型信息将在编译处理是被擦除,这个过程即类型擦除。
当然你只要记住以下几点:
- 虚拟机中没有泛型,只有普通类和普通方法
- 所有泛型类的类型参数在编译时都会被擦除
- 创建泛型对象时请指明类型(有约束力更安全),让编译器尽早的做参数检查(Effective Java,第23条:请不要在新代码中使用原生态类型),
- 不要忽略编译器的警告信息,那意味着潜在的ClassCastException等着你
好吧,扯远了!回归主题,桥接方法为了使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);
}
}
/**
* 编译时去掉泛型(泛型擦除)后是这样的,泛型T都被替换为了Object
**/
public interface SuperClass {
void method(Object t);
}
public class AClass implements SuperClass {
public void method(String s) {
System.out.println(s);
}
public void method(Object s) {//桥接方法
this.method((String) s);
}
}
如何验证上面的结论呢?
通过命令,javap -p AClass.class
到这里基本上就结束了,掌握一个东西可以通过以点(某个特性)到面,最后层层深入。