我有一个带有泛型的课程。我知道泛型类型信息在运行时被剥离,但这是绑定类型。我认为在编译时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{}
答案 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
由于Litter
是raw 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
类型的变量。
有什么我想念的东西可以让我的工作像我想要的那样吗?
不是原始类型,不是。