2013-04-02 25 views
1

我有以下的通用類:與列表<String>原始類型提供了編譯錯誤

import java.util.ArrayList; 
import java.util.List; 

public class GenericRaw<T> { 
    public List<String> get() { 
     return new ArrayList<>(); 
    } 
} 

讓我們看看它的使用的情況下:

public class Usage { 
    public void doSomething() { 
     GenericRaw base = new GenericRaw(); 
     for (String x : base.get()) { } 
    } 
} 

對於這個代碼理念不給任何編譯錯誤,但Java編譯器本身:

java:不兼容的類型 必需:java.lang.String 發現:java.lang.Object繼承

上重現JDK 1.6.0_33以及對JDK 1.7.0_17。

有人可以幫我解釋這個問題嗎?

我調查的結果。 以下變體可成功編譯:

public void doSomething() { 
    GenericRaw<?> base = new GenericRaw(); 
    for (String x : base.get()) { } 
} 

甚至:

public void doSomething() { 
    GenericRaw base = new GenericRaw(); 
    List<String> list = base.get(); 
    for (String x : list) { } 
} 
+0

我同意這是重複的[http://stackoverflow.com/questions/11007723/combining-raw-types-and-generic-methods](http://stackoverflow.com/questions/11007723/combining -raw-types-and-generic-methods)就在不同的條件下。 –

回答

3

有人可以幫助我這個問題的解釋呢?

肯定。它的下面的原料類型的JLS的描述,在section 4.8

爲了促進與非通用遺留碼接口,有可能作爲一種類型使用擦除(§4.6)的參數化類型的(§4.5)或擦除其元素類型爲參數化類型的數組類型(第10.1節)。這種類型被稱爲原始類型。

GenericRaw<T>erasure是:

public class GenericRaw { 
    public List get() { ... } 
} 

因爲:

類型擦除也映射簽名(§8.4.2)構造或方法不具有一個簽名的參數化類型或類型變量。構造函數或方法簽名的刪除是一個由與s相同名稱和s中所有形式參數類型的刪除組成的簽名。

構造函數或方法(第8.4.4節)的類型參數以及方法的返回類型(第8.4.5節)在擦除構造函數或方法的簽名時也會進行擦除。

+0

非常感謝您的幫助! –