私はジェネリックのクラスを持っています。私は、ジェネリック型の情報が実行時に削除されることを知っていますが、これはバウンド型です。コンパイル時にjava.lang.Object
がバインドされた型に置き換えられたと私は考えました。すべてが常に少なくともAnimal
であることを知っているなら、コンパイラはそれをObject
のままにしていますか?私が欲しいのと同じようにこの仕事をするために欠けているものがありますか?具体的には、その最後の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{}
すべてのコンパイラ警告をオンにすると、 'litter'の生の型を使用していることがわかります。これは基本的にコンパイラにその文のジェネリックの存在を無視させます。 – VGR
タイプが指定されていない場合は、すべての汎用情報が削除されます。オブジェクトはそのままです。 – Bohemian
それはあまり単純ではありません@ボヘミアン。有界型は規則を少し変更します。 Sotiriosが示しているように、TがAnimalを継承しているときに通常Tを返すインスタンスメソッドは、生の型のAnimalを返します。私の混乱は、IteratorがAnimalにパラメータ化されていない理由です。 – bmauter