Java 类型擦除和桥接方法

Java 类型擦除和桥接方法,java,generics,compiler-construction,bridge,Java,Generics,Compiler Construction,Bridge,考虑以下代码: List<Integer>ints= new ArrayList<Integer>(); lst.add(new Object());//no suitable method found for add(Object)... 类型擦除发生在编译器执行类型检查之后。如果情况正好相反,那么泛型就没有意义了 类型擦除发生在编译器执行类型检查之后。如果情况正好相反,那么泛型就没有意义了 您不是在评估 lst.add(new Object()); 在运行时,您

考虑以下代码:

List<Integer>ints= new ArrayList<Integer>();
lst.add(new Object());//no suitable method found for add(Object)...
类型擦除发生在编译器执行类型检查之后。如果情况正好相反,那么泛型就没有意义了

类型擦除发生在编译器执行类型检查之后。如果情况正好相反,那么泛型就没有意义了

您不是在评估

lst.add(new Object()); 
在运行时,您将在编译时对其进行评估。在编译时,没有方法
List#add(Object)

您没有评估

lst.add(new Object()); 

在运行时,您将在编译时对其进行评估。编译时,没有方法
List#add(Object)

桥接方法进入类定义,而不是方法,例如:

public class Test implements Comparable<Test> {

    public int compareTo(Test o) {
        return ...;
    }
...

由于字节码中的可比较接口具有
int compareTo(Object o)
方法,并且为了让JVM检测到类实现了此方法,类需要
int compareTo(Object o)
桥接方法在类定义中,而不是在方法中,例如:

public class Test implements Comparable<Test> {

    public int compareTo(Test o) {
        return ...;
    }
...


因为字节码中的可比较接口有
int compareTo(Object o)
方法,为了让JVM检测到类实现了这个方法,类需要
int compareTo(Object o)

,如果我们不能称他为桥接方法,我们需要什么?@St.Antario:对不起,我不明白你在问什么。@St.Antario。桥接方法由编译器生成。所以,你不能打电话给他们,因为他们在运行时才存在。@Oli Charlesworth添加了什么桥接方法?@St.Antario:这里解释:。如果我们不能打电话给他,需要什么桥接方法?@St.Antario:对不起,我不明白你在问什么。@St.Antario。桥接方法由编译器生成。所以,您不能调用它们,因为它们在运行时之前不存在。@Oli Charlesworth添加了什么桥接方法?@St.Antario:这里解释:。您正在尝试将对象添加到整数列表中!你为什么认为这会起作用?这正是泛型的用途。定义的
lst
位置可能重复?您正在尝试将对象添加到整数列表中!你为什么认为这会起作用?这正是泛型的目的。可能重复定义了
lst
的位置?它是
public int compareTo(Object o){return compareTo((Test)o);}
,否则它就不是“桥”。如果一个子类“代码>测试重写<代码> COMPARETO(测试O)<代码>,请考虑以下代码:<代码>列表Its= NealRayayList.()ints.add(5):如果编译器不生成桥接方法,在这种特定情况下会发生什么?是否在类型检查之后和类型擦除之前生成桥接方法?@St.Antario:否。使用泛型类不会创建任何桥接方法。因此,使用
ArrayList
不会创建桥接方法。看看上面的例子。它实现了一个带有绑定类型参数的通用接口。这是一种创建桥接方法的情况。与实例化泛型类完全不同。@Holger为什么在我的例子中没有桥接方法?ArrayList是AbstractList的子类。编译扩展参数化类或实现参数化接口的类或接口时,编译器可能需要创建称为桥接方法的合成方法,作为类型擦除过程的一部分。编译器可能会创建桥接方法。由于
ArrayList
不会更改
AbstractList
的类型参数
的边界,因此不需要桥接方法。原始类型的方法仍然使用
Object
,其中泛型类型具有
E
。它是
public int compareTo(Object o){return compareTo((Test)o);}
,否则它就不是“桥”。如果一个子类“代码>测试重写<代码> COMPARETO(测试O)<代码>,请考虑以下代码:<代码>列表Its= NealRayayList.()ints.add(5):如果编译器不生成桥接方法,在这种特定情况下会发生什么?是否在类型检查之后和类型擦除之前生成桥接方法?@St.Antario:否。使用泛型类不会创建任何桥接方法。因此,使用
ArrayList
不会创建桥接方法。看看上面的例子。它实现了一个带有绑定类型参数的通用接口。这是一种创建桥接方法的情况。与实例化泛型类完全不同。@Holger为什么在我的例子中没有桥接方法?ArrayList是AbstractList的子类。编译扩展参数化类或实现参数化接口的类或接口时,编译器可能需要创建称为桥接方法的合成方法,作为类型擦除过程的一部分。编译器可能会创建桥接方法。由于
ArrayList
不会更改
AbstractList
的类型参数
的边界,因此不需要桥接方法。原始类型的方法仍然使用
Object
,其中泛型类型具有
E