2013-07-30 38 views

回答

6

原因是您聲明變量a是一個原始列表即List沒有任何關聯的類型:

List a = new ArrayList<String>(); 

對於這個問題,即使這將編譯&運行:

List a = new ArrayList<Date>(); 
a.add(new Integer(5)); 

另外還有關於genericstype erasure的說明:

泛型是由Java編譯器實現的,稱爲擦除的前端轉換。 類型刪除適用於泛型的使用。當使用泛型時,它們被轉換爲編譯時檢查並運行時間類型轉換。

由於類型擦除機制驗證碼:

List<String> a = new ArrayList<String>(); 
a.add("foo"); 
String x = a.get(0); 

被編譯成:

List a = new ArrayList(); 
a.add("foo"); 
String x = (String) a.get(0); 

同樣代碼:

List a = new ArrayList<String>(); 
a.add(new Integer(5)); 

被編譯成這個(由於類型擦除):

List a = new ArrayList(); 
a.add(new Integer(5)); 

因此沒有編譯或運行時錯誤產生。

然而,你將注意區別,當你嘗試做從列表中獲取項目:

int i = a.get(0); // compilation error due to type mismatch 

這是由於你的名單被聲明爲原始類型的事實。爲了避免這個錯誤,你需要使用泛型來聲明你的列表,或者像上面那樣進行類型轉換。即

無論是在你的列表中使用泛型類型:

List<Integer> a = new ArrayList<Integer>(); 
a.add(new Integer(5));  
int i = a.get(0); 

要不要這樣做鑄造:(不推薦

List a=new ArrayList<Date>(); 
a.add(new Integer(5)); 
int i = (Integer) a.get(0); 

PS:注意,在運行時有沒有找出那種特殊類型的方式,例如字符串用於聲明你的列表對象。

1

如果你寫

List<String> a = new ArrayList<String>(); 
a.add(new Integer(5)); 

不會編譯沒有指定在實際定義

泛型類型。

+0

我知道了,謝謝。我想知道爲什麼它沒有任何異常運行 –

+0

它的運行沒有例外,因爲ArrayList使用引擎蓋下的Object []來存儲數據,而Integer是Object的子類 –

1

你應該做

List<String> a = new ArrayList<String>(); 
a.add(new Integer(5)); 
  • 名單意味着,編譯器將只檢查String對象是否被添加到集合。

有人可以解釋一下嗎?

這是可能的,因爲

  • 有一個在因爲類型的運行時沒有任何類型的安全erasuse
  • 聲明List a意味着有什麼對象被添加到列表中沒有編譯時檢查。

從java 7開始,您不必爲類型安全編寫List<String> a = new ArrayList<String>()。您可以簡單地使用鑽石操作員,並實現相同的使用List<String> a = new ArrayList();

1

List a是一種原始類型,它是沒有泛型。這與你能夠將整數添加到它完全相同的原因。

要強制執行正確的行爲,請將List更改爲使用泛型。

List<String> a 
1

編譯後刪除通用數據。這意味着

List<String> a=new ArrayList<String>(); 

將被更改爲你所看到的下面,在類文件

List a=new ArrayList(); 

現在回答你的問題,的a類型是List,這是生名單和你可以給添加任何東西。仿製藥目前存在編譯時間限制。這意味着說你有

List<String> a=new ArrayList<String>(); 

這條線將產生編譯時錯誤

a.add(new Integer(1)); //error 
1

這是因爲舊的遺留代碼被允許把任何東西(除了 元)到一個集合。並且爲了支持遺留代碼,Java 5和Java 6 允許您的新類型安全代碼使用舊代碼。

因此,Java 5或Java 6編譯器被迫讓你編譯你的新類型 安全代碼,即使你的代碼調用了一個老類的方法,它需要一個非類型安全的參數,並知道誰知道什麼用它。

實際上,編譯器會警告你。編譯器從編譯生成了一個完全有效的類文件,但用這麼多的話來告訴你,我真的很希望你知道你在做什麼因爲這個舊代碼不會對你的<String>打字產生任何尊重(甚至不知道),並且可以做任何你想要的珍貴ArrayList<String>。「