2008-11-13 55 views
1

下面的代碼無法編譯:引入泛型的Java代碼,而不破壞構建

public class GenericsTest {  
    public static void main(String[] args) { 
     MyList<?> list = new MyList<Object>(); 
     Class<?> clazz = list.get(0); 

     // Does not compile with reason 
     // "Type mismatch: cannot convert from Object to Class" 
     MyList list2 = new MyList(); 
     Class clazz2 = list2.get(0); 
    } 
    static class MyList<T> extends ArrayList<Class<T>> { 
    } 
} 

我想這樣做是爲了引入泛型的舊代碼,而不破壞構建。

這是編譯器(eclipse和javac)中的錯誤還是我在這裏丟失了一些東西?將泛型引入MyList還有什麼其他可能性?

編輯

對於澄清:

我有泛型類

public class MyList extends ArrayList<MyObject> {} 

public class MyObject {} 

,並使用MYLIST

代碼3210
MyList list = new MyList(); 
... 
MyObject o = list.get(0); 
發展中,我看到我要介紹的泛型MYOBJECT

public class MyObject<T> {} 

,現在我想有MYLIST這個新的通用啄以及

public class MyList<T> extends ArrayList<MyObject<T>> {} 

期間

現在但這並突破我的構建。有趣的是

public class MyList<T> extends ArrayList<MyObject<T>> { 
    public MyObject<T> get(int i) { 
     return super.get(i); 
    } 
} 

將使舊的代碼

MyList list = new MyList(); 
... 
MyObject o = list.get(0); 

編譯。

好的,似乎當我引入這個泛型時,我將不得不將所有對MyList的調用改爲泛型。我希望舊代碼只引入警告而不是錯誤。

+0

如果您提供編譯錯誤以及代碼,這將有所幫助。 – Herms 2008-11-13 16:34:27

+0

編譯錯誤在示例中的註釋中。 – 2008-11-13 17:00:54

回答

12

我覺得你根本不瞭解仿製藥相當如何工作。

MyList<?> list = new MyList<Object>(); 
Class<String> clazz= list.get(0); 

這段代碼不能編譯,因爲你是在告訴list將要舉辦Class<Object>類型的編譯器 - 然後在下一行你期望它返回你一個Class<String>。 Java中的通用系統無法像您認爲的那樣將基於繼承的泛型轉換爲類型。

如果您希望list擁有Class<String>,那麼您需要將其聲明爲 - 或者,如果您希望它能夠容納任何類型,則不能在沒有強制轉換的情況下執行第二行。

MyList<String> list = new MyList<String>(); 
Class<String> clazz = list.get(0); 

MyList<?> list = new MyList<Object>(); 
//generates a warning about an unchecked cast 
Class<String> clazz = (Class<String>) list.get(0); 

的第二代碼片段無法正常工作,因爲當你使用原始的類型,你仍然需要通過get()投返回Object您所使用聲明的類型(這一直是這種情況)。

MyList list2 = new MyList(); 
Class clazz2 = (Class) list2.get(0); 
+0

我覺得你還沒有看到類MyList的聲明在最後:static class MyList extends ArrayList >。有定義,MyList 需要類 -Objects。 – Mnementh 2008-11-13 16:39:35

1

我沒有在這臺機器上的編譯器,但這應該工作。

public class GenericsTest {  
    public static void main(String[] args) { 
     MyList<Object> list = new MyList<Object>(); 
     Class<?> clazz= list.get(0); 

    } 


    static class MyList<T> extends ArrayList<Class<? extends T>> { 
    } 
} 
1

在您的例子是MYLIST要更新到支持泛型的舊代碼?如果是這樣,我的列表應該包含什麼類型的對象?

正如在別處提到的那樣,編譯錯誤是有效的。這是由於原始列表正在被訪問而沒有被轉換爲Class。因此,代碼試圖將一個對象分配給一個類的引用。它相當於這樣:

Object o = new Object(); 
Class c = o; 

哪個根本無法編譯。此外,要充分利用仿製藥,您應該贊成類<? >而不是Class。

0

在您的示例中,第二個示例不起作用,因爲您沒有使用泛型,因此它意味着get()方法將返回一個Object,並且您需要將其轉換爲Class。當您沒有爲您的MyList指定類型時:

MyList list2 = new MyList();

然後,你正在失去泛型優點,你需要在調用get()方法時拋出對象,就像在良好的日子裏一樣。