有界泛型类型的擦除是什么?

时间:2017-02-22 17:22:26

标签: java generics

我有一个带有泛型的课程。我知道泛型类型信息在运行时被剥离,但这是绑定类型。我认为在编译时java.lang.Object被绑定类型替换。如果我知道一切都至少是Animal,那么为什么编译器会将其保留为Object?有什么我想念的东西会让我的工作像我想要的那样吗?具体来说,main方法中的最后一个for循环存在编译时问题。

谢谢!

public static void main( String[] args ) throws Exception {

    Litter<Cat> catLitter = new Litter<>();
    for( Cat cat : catLitter ) {}

    Litter<Animal> animalLitter = new Litter<>();
    for( Animal animal : animalLitter ) {}

    Litter litter = new Litter();
    for( Animal animal : litter ) {} // Type mismatch: cannot convert from element type Object to Animal
}

public class Litter<T extends Animal> implements Iterable<T>{
    @Override public java.util.Iterator<T> iterator() {
        return new LitterIterator();
    }

    class LitterIterator implements java.util.Iterator<T> {
        @Override public boolean hasNext() { return false; }
        @Override public T next() { return null; }
    }
}

public class Animal {}
public class Dog extends Animal{}
public class Cat extends Animal{}

1 个答案:

答案 0 :(得分:4)

强制重定向:

您期望的行为将适用于

之类的行为
public class Litter<T extends Animal> implements Iterable<T>{
    public T get() {return null; /* or whatever */}
    ...
}

Litter litter = ...; // raw type 
Animal animal = litter.get(); // compiles fine

由于Litterraw type

  

构造函数的类型(§8.8),实例方法(§8.4,§9.4),或者   原始类型C的非静态字段(第8.3节),它不是从其继承的   超类或超接口是对应的原始类型   在与C

对应的通用声明中删除其类型

以及

  

类型变量(第4.4节)的擦除是其最左边界的擦除。

然后方法get显示为

public Animal get() {...}

使用原始Litter类型进行编码。

然而,对于Litter#iterator(),其返回类型为Iterator<T>,因为

  

参数化类型(第4.5节)G<T1,...,Tn>的删除是|G|

它的删除只是Iterator。然后next() Iterator方法将被删除为

public Object next() {...}

很明显,它的返回值不能分配给Animal类型的变量。

  

有什么我想念的东西可以让我的工作像我想要的那样吗?

不是原始类型,不是。