2010-05-20 171 views
7

請幫我這個:Java的泛型集合

如果Lion IS-A Animal並給予Cage<T>

Cage<? extends Animal> c = new Cage<Lion>(); // ok, 

Set<Cage<? extends Animal>> cc = new HashSet<Cage<Lion>>(); // not ok 

我看不出這裏有什麼?

回答

6

使用非通配類型T分配給變量(Set<T>)時,被分配的對象必須具有T作爲其通用類型(包括所有通用類型參數T,通配符和非通配符)。在你的情況下,TCage<Lion>,它與Cage<? extends Animal>不同。

你能做什麼,因爲Cage<Lion>是分配給Cage<? extends Animal>,是使用通配符類型:

Set<? extends Cage<? extends Animal>> a = new Set<Cage<Lion>>(); 
+0

+1爲實際解決方案。 – 2010-05-20 19:50:16

+0

謝謝,對我來說,那是缺失的部分。 – 2010-05-23 17:26:53

6

這是錯誤的,因爲如果允許,那麼這將是合法的:

Set<Cage<? extends Animal>> cc = new HashSet<Cage<Lion>>(); 
cc.add(new Cage<Tiger>()); // legal -- Cage<Tiger> is a Cage<? extends Animal> 

Cage<Tiger>是宣言的範圍內,但沒有定義,所以這會崩潰。

+0

如何Java的決定是否申請逆變/協方差或不? – Simon 2010-05-20 18:21:48

+0

我的理解Java將泛型視爲不變(但奇怪的是,將數組視爲協變和類型檢查在運行時),但通過使用合適的通配符(適當擴展或超級)參數編寫方法,以及一些鑄造和抑制未檢查的轉換,你可以給你一個合適的印象。 – pdbartlett 2010-05-20 18:33:44

2

您需要:

Set<? extends List<? extends Number>> cc = new HashSet<ArrayList<Integer>>(); 

要解釋爲什麼...我想備份到一個簡單的版本的例子:

Number a = new Integer(1); // OK 
Set<Number> b = new HashSet<Integer>(); // not OK 

這不起作用,因爲它將使

b.add(new Double(3.0));