我認爲我對Java泛型有一些很好的理解。當類是泛型時Java通配符的奇怪行爲
This code DOES NOT COMPILE我知道爲什麼。
我們可以通過測試方法只動物類型的列表或它的超類型(如對象的列表)
package scjp.examples.generics.wildcards;
import java.util.ArrayList;
import java.util.List;
class Animal {}
class Mammal extends Animal {}
class Dog extends Mammal {}
public class Test {
public void test(List<? super Animal> col) {
col.add(new Animal());
col.add(new Mammal());
col.add(new Dog());
}
public static void main(String[] args) {
List<Animal> animalList = new ArrayList<Animal>();
List<Mammal> mammalList = new ArrayList<Mammal>();
List<Dog> dogList = new ArrayList<Dog>();
new Test().test(animalList);
new Test().test(mammalList); // Error: The method test(List<? super Animal>) in the type Test is not applicable for the arguments (List<Mammal>)
new Test().test(dogList); // Error: The method test(List<? super Animal>) in the type Test is not applicable for the arguments (List<Dog>)
Dog dog = dogList.get(0);
}
}
但是這裏來了奇怪的一部分(至少對我來說)。
如果我們只會增加<牛逼>聲明類測試作爲通用的,那麼它編譯!並拋出java.lang.ClassCastException:
public class Test<T> {
...
}
,
Exception in thread "main" java.lang.ClassCastException: scjp.examples.generics.wildcards.Animal cannot be cast to scjp.examples.generics.wildcards.Dog
我的問題是,爲什麼將通用類型<牛逼>(未在任何地方使用)引起的類編譯和改變通配符的行爲?
+1。我應該補充一點,即使它在Eclipse中編譯,它肯定會產生一系列可怕的警告,您應該注意這些警告。 – 2011-05-16 21:42:12
實際上不只是eclipse,該規範強制要求警告:「如果刪除更改了方法或構造函數的任何參數的任何類型,則對原始類型的方法或構造函數的調用將生成未經檢查的警告。通常,在運行時幾乎所有可能導致*堆污染*的代碼都需要在編譯時生成未經檢查的警告。 – meriton 2011-05-16 21:55:10