2013-10-18 47 views
2

在Java教程(http://docs.oracle.com/javase/tutorial/extra/generics/fineprint.html)我看到以下內容:爲什麼Java中允許使用未知通用類型的數組?

// Not really allowed. 
List<String>[] lsa = new List<String>[10]; 
Object o = lsa; 
Object[] oa = (Object[]) o; 
List<Integer> li = new ArrayList<Integer>(); 
li.add(new Integer(3)); 
// Unsound, but passes run time store check 
oa[1] = li; 

// Run-time error: ClassCastException. 
String s = lsa[1].get(0); 
If arrays of parameterized type were allowed, the previous example 
would compile without any unchecked warnings, and yet fail at run-time 


// OK, array of unbounded wildcard type. 
List<?>[] lsa = new List<?>[10]; 
Object o = lsa; 
Object[] oa = (Object[]) o; 
List<Integer> li = new ArrayList<Integer>(); 
li.add(new Integer(3)); 
// Correct. 
oa[1] = li; 
// Run time error, but cast is explicit. 
String s = (String) lsa[1].get(0); 

然後,他們解釋說,如果我們切換到List<String>[] lsa = new List<String>[10]; List<?>[] lsa = new List<?>[10];那麼也沒關係,但我們必須上溯造型。

我的一個教授問了下面這個:「爲什麼後者會編譯?」

然後他給出了答案:「當參數是?的意思是數組中的每個單元格都可以包含一個ArrayList。因爲沒有任何有關泛型類型的假設,所以以前的異常不能發生。」

對於我來說,通配符的工作仍然沒有意義,而前一個沒有。如果我們必須在通配符示例中強制實施上傳,爲什麼我們不能在第一個示例中執行該操作?

如果有人能爲我解決這個問題,我將不勝感激。

+0

的[什麼是與創建通用陣列的問題?]可能重複(http://stackoverflow.com/questions/18581002/whats-the-issue-with-creating-a-generic-array) –

回答

0

泛型被設計成在您提供某種類型時是類型安全的。但由於類型擦除,完全可以存儲在通用列表中的信息將丟失。這與您只提供?作爲類型具有相同的效果。在運行時不能確定類型總是正確的,因此編譯器會抱怨。

這兩個版本中的數據將是相同的,但其中一個版本編譯,另一個版本不會。這是因爲在提供通配符時,基本上關閉編譯器的類型安全性(如交換機),並告訴它你會自己關心它。如果它失敗了,那將是你自己的錯,而不是編譯器的錯誤了。 :)

1

這張通配牌迫使你施放,所以你應該知道真正的課程。

第一種情況(如果可能的話)會給你一種虛假的安全感和沒有警告,因爲泛型的全部意義在於允許你在不需要不斷鑄造的情況下工作。

0

第一個不允許的實際原因是因爲java的類型系統不健全。

規範說如果S是-a T,那麼S[]是-。不幸的是該規則使類型的問題,即:

void unsoundness(Animal[] aanl) { 
    // causes a runtime type check that the element types are compatible 
    aanl[ 0 ] = new Animal(); 
} 

Dog[] adog = new Dog[ 1 ]; 
unsoundness(adog); 

有了泛型和類型擦除,即運行時類型檢查不能做出正確的決定。

void unsoundness(List< ? extends Animal >[] alstr) { 
    alstr[ 0 ] = new ArrayList<Animal>(); 
} 

List<Dog>[] alobj = new List<Dog>[ 1 ]; // fictitious 
unsoundness(alobj); 
相關問題