在JDK 1.5 引入泛型后就引入了桥接方法,也可以理解为桥接方法是泛型的本质(载体)泛型只是表象。熟悉泛型的童靴可能都知道,Java泛型的处理几乎都在编译器中进行,编译器生成的bytecode是不包涵泛型信息的,泛型类型信息将在编译处理是被擦除,这个过程即类型擦除。

当然你只要记住以下几点:

  1. 虚拟机中没有泛型,只有普通类和普通方法
  2. 所有泛型类的类型参数在编译时都会被擦除
  3. 创建泛型对象时请指明类型(有约束力更安全),让编译器尽早的做参数检查(Effective Java,第23条:请不要在新代码中使用原生态类型),
  4. 不要忽略编译器的警告信息,那意味着潜在的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

到这里基本上就结束了,掌握一个东西可以通过以点(某个特性)到面,最后层层深入。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐