Java泛型 - Bridge方法? [英] Java Generics - Bridge method?

查看:72
本文介绍了Java泛型 - Bridge方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关Java泛型的桥接方法概念让我停下来想一想。


顺便说一句,我只知道它出现在
字节码级别,并且不可用
供我们使用。

但我很想知道Java编译器使用的桥接方法背后的概念。

幕后发生了什么以及为什么会使用它?



任何有关示例的帮助都将不胜感激。

解决方案

这是一种允许扩展泛型类或实现泛型接口的类(具有具体类型参数)用作原始类型。



试想一下:

  public类MyComparator实现了Comparator< Integer> {
public int compare(Integer a,Integer b){
//
}
}

这不能用于原始形式,传递两个 Object s进行比较,因为类型被编译到比较方法(与将会发生的是它是通用类型参数T,其中类型将被擦除)相反。相反,在幕后,编译器添加了一个桥接方法,它看起来像这样(是Java源代码):

  public class MyComparator实现了Comparator< Integer> {
public int compare(Integer a,Integer b){
//
}

//这是一个桥接方法
public int比较(对象a,对象b){
返回比较((整数)a,(整数)b);






编译器保护对桥接方法的访问,直接显式调用它会导致编译时错误。现在这个类还可以以其原始形式使用:

  Object a = 5; 
Object b = 6;

比较器rawComp = new MyComparator();
int comp = rawComp.compare(a,b);



为什么还需要它?



除了增加对显式使用原始类型的支持(主要是为了向后兼容)桥接方法也需要支持类型擦除。使用类型擦除,像这样的方法:

  public< T> T max(List< T> list,Comparator< T> comp){
T largestSoFar = list.get(0);
for(T t:list){
if(comp.compare(t,largestSoFar)> 0){
largestSoFar = t;
}
}
return largestSoFar;
}

实际上被编译为与此兼容的字节码:

  public Object max(List list,Comparator comp){
Object largestSoFar = list.get(0);
for(Object t:list){
if(comp.compare(t,largestSoFar)> 0){//重要
largestSoFar = t;
}
}
return largestSoFar;





$ b如果桥接方法不存在并且你传递了一个列出<整数> 和一个 MyComparator 到这个函数,标记重要会失败,因为 MyComparator 不会有任何叫做 compare 的方法,它需要两个 Object s...只有一个需要两个整数 s。



下面的FAQ是 ://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ102rel =noreferrer>泛型常见问题 - 什么是桥接方法?

  • Java桥接方法解释(感谢 @Bozho


  • Something called the "bridge method" concept related to Java Generics made me stop at a point and think over it.

    Btw, I only know that it occurs at the bytecode level and is not available for us to use.

    But I am eager to know the concept behind the "bridge method" used by the Java compiler.

    What exactly happens behind the scenes and why it is used?

    Any help with an example would be greatly appreciated.

    解决方案

    It's a method that allows a class extending a generic class or implementing a generic interface (with a concrete type parameter) to still be used as a raw type.

    Imagine this:

    public class MyComparator implements Comparator<Integer> {
       public int compare(Integer a, Integer b) {
          //
       }
    }
    

    This can't be used in its raw form, passing two Objects to compare, because the types are compiled in to the compare method (contrary to what would happen were it a generic type parameter T, where the type would be erased). So instead, behind the scenes, the compiler adds a "bridge method", which looks something like this (were it Java source):

    public class MyComparator implements Comparator<Integer> {
       public int compare(Integer a, Integer b) {
          //
       }
    
       //THIS is a "bridge method"
       public int compare(Object a, Object b) {
          return compare((Integer)a, (Integer)b);
       }
    }
    

    The compiler protects access to the bridge method, enforcing that explicit calls directly to it result in a compile time error. Now the class can be used in its raw form as well:

    Object a = 5;
    Object b = 6;
    
    Comparator rawComp = new MyComparator();
    int comp = rawComp.compare(a, b);
    

    Why else is it needed?

    In addition to adding support for explicit use of raw types (which is mainly for backwards compatability) bridge methods are also required to support type erasure. With type erasure, a method like this:

    public <T> T max(List<T> list, Comparator<T> comp) {
       T biggestSoFar = list.get(0);
       for ( T t : list ) {
           if (comp.compare(t, biggestSoFar) > 0) {
              biggestSoFar = t;
           }
       }
       return biggestSoFar;
    }
    

    is actually compiled into bytecode compatible with this:

    public Object max(List list, Comparator comp) {
       Object biggestSoFar = list.get(0);
       for ( Object  t : list ) {
           if (comp.compare(t, biggestSoFar) > 0) {  //IMPORTANT
              biggestSoFar = t;
           }
       }
       return biggestSoFar;
    }
    

    If the bridge method didn't exist and you passed a List<Integer> and a MyComparator to this function, the call at the line tagged IMPORTANT would fail since MyComparator would have no method called compare that takes two Objects...only one that takes two Integers.

    The FAQ below is a good read.

    See Also:

    这篇关于Java泛型 - Bridge方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆