2011-03-21 76 views
5

搜索了一陣後,我仍然找不到任何回答我的問題,甚至還有幾個相關主題泛型的,所以在這裏你去:上的Java泛型約束通配符

ArrayList<? super IOException> list = new ArrayList<Exception>(); 
list.add(new FileNotFoundException("this is ok.")); 
list.add(new IOException("This is ok")); 
list.add(new ClassCastException("compile err"));//why compile err? 
list.add(new Exception("compile err"));//why compile err? 

爲什麼最後兩行不會編譯?特別是最後一行。我對這個主題做了很多測試,但仍然無法理解這個邏輯。

謝謝。

回答

8

ArrayList<? super IOException>可能是下列任何一種(因爲通配符):

ArrayList<IOException> 
ArrayList<Exception> 
ArrayList<Throwable> 
ArrayList<Object> 

代碼需要與所有四種可能性工作。

但是,如果是ArrayList<IOException>,則不能輸入ClassCastExceptionException,因此編譯錯誤。

下面是我沒有得到:爲什麼這一個編譯------ >>> list.add(新的FileNotFoundException(「這是好的。」)); < < < ----我覺得FileNotFoundException也在IOException的邊界之下。但它編譯好。

不,FileNotFoundException沒問題,因爲它擴展了IOException,你可以把它放在所有這四種類型的列表中。

注意,由於歷史原因,數組沒有得到同樣嚴格的類型檢查,你可以編譯下面(然後在運行時獲取一個數組店除外):

Exception[] a = new IOException[4]; 
    a[0] = new FileNotFoundException("this is ok."); 
    a[1] = new IOException("This is ok"); 
    a[2] = new ClassCastException("compiles, but boom!"); 
    a[3] = new Exception("compiles, but boom!"); 
+0

@凱這有助於清楚地回答你的問題。 – asgs 2011-03-21 08:47:51

+0

謝謝,湯姆,這裏是我沒有得到:爲什麼這一個編譯------ >>> list.add(新的FileNotFoundException(「這是好的。」)); <<< ----我認爲FileNotFoundException也低於IOException的邊界。但它編譯好。 – 2011-03-21 08:52:51

+0

經過一段時間的摘要後,終於明白了:)即使在line1之後,list = new ArrayList (),但是list的元素的基類仍然被限制在滿足條件「?super IOException」的類中,換句話說,元素的基類需要至少(或子類)IOException。 – 2011-03-21 09:14:21

1

Exception是超級類別IOException延伸Exception。你可以使用:

List<Exception> list = new ArrayList<Exception>(); 
list.add(...); // any exception 

然後它會編譯所有異常類型。

+0

是的,我知道,但我仍然需要了解問題的原因。不管怎麼說:) – 2011-03-21 08:41:52

+1

對不起,但是這並不回答我的問題:(。 – 2011-03-21 08:46:05

+0

我的意思是第一行的有效性(列表的定義是有效的),以及編譯器失敗最後兩行的邏輯是什麼line? – 2011-03-21 08:47:34

0

我想是因爲最後一個異常不從基類派生IOException異常

+0

我認爲恰恰相反:因爲'super'表示任何「IOException基於」的類應該是有效的,例如'Exception'或'Object',但似乎這隻對第一行是正確的,但是( – 2011-03-21 08:39:36

4

考慮的list相同的聲明,但有不同的任務:

ArrayList<? super IOException> list = new ArrayList<IOException>(); 

中的類型沒有變化list,但現在添加ClassCastExceptionException顯然是錯誤的。

+0

)你可能會更具體嗎?請詳細說明一下,我認爲你是瞭解我的問題的核心人物,所以請給出更多的細節。 – 2011-03-21 08:45:15

+0

@Kai什麼都不是,你得到了嗎?它是引用的類型很重要嗎?或者你不應該能夠給'ArrayList '添加一個'Exception'?或者通常可能是對'ArrayList'的另一個引用與不同(但是正確)邊界? – 2011-03-21 08:48:10

+0

或任何人都可以擴大這個答案更詳細請,例如? – 2011-03-21 08:49:02

0

根據你的ArrayList參考通用聲明,只能將實際的IOException(由於?super)或將IOException擴展到的對象添加到列表中。

ClassCaseException和Exception不是從IOException派生的,因此它失敗。

1

對我來說這是指較低的通配符通配符:<? super IOException>。上界有通配符將是<? extends IOException>

您示例中的通配符似乎只在分配給變量的新行Object的行中有效。後來訪問時,顯然不再有效。這就和ArrayList<IOException>一樣。

所以你對自己的解釋顯然是錯誤的。上界和下界意味着它所說的。