2011-06-29 31 views
10

我已經進入了一些我以前沒有遇到過的Java,也就是說,我需要在運行時創建一個新的實例來說明ArrayList類,而不指定已知類型,然後將數據添加到列表中。這聽起來有點含糊所以這裏有一個例子:Java添加到未知類型的通用列表

Class<?> c = i.getClass(); 

Constructor<?> con = ArrayList.class.getConstructor(); 
ArrayList<?> al = (ArrayList<?>)con.newInstance(); 

al.add("something"); 

我現在做這個而不只是使用泛型的理由是因爲仿製藥已經被大量使用和「我」在這個例子中的變量將被給予用作類型「?」。我真的不想扔另一個通用的,因爲這會給用戶帶來更多的工作,並且在最終設計中會更不靈活。有什麼方法可以使用下面的東西(注意:下面的東西不起作用)。任何人有想法?

ArrayList<c> al = (ArrayList<c>)con.newInstance(); 
+3

泛型用於編譯時驗證。在運行時,你可能不用擔心泛型類型,只是使用非泛型的'ArrayList'。 –

+0

@Bala R你說得對,我可以刪除泛型,我只是想知道是否有辦法將它從類中拉出來以確保驗證。謝謝,你的想法可能會爲我的目的。 – ars265

+0

我不得不問,列表的目的是什麼,你不知道它將包含的數據的類型? – Bringer128

回答

7

您不能在使用通配符泛型定義的集合中添加對象。 This thread可能會幫助你。事實上,你正在創建一個集合,是的,每個集合的超類型,因此可以分配給任何泛型集合;但是它太泛化了,不允許任何類型的添加操作,因爲編譯器無法檢查您添加的內容的類型。這正是泛型的意義所在:類型檢查。

我建議你閱讀這篇文章,看看它也適用於你想做的事。

您的集合太泛化,無法添加任何東西。問題與asignment的右側無關(使用單例或反射),它使用通配符在左側聲明類型中。

5

如果我明白你的意思,你有一個C類,它在編譯時是未知的,你想創建一個ArrayList<C>,類型安全的方式。這是可能的:

Class<?> c = ...; 
ArrayList<?> al = listOf(c); 

static <T> ArrayList<T> listOf(Class<T> clazz) 
{ 
    return new ArrayList<T>(); 
} 

這是做它的理論上正確的方法。但誰在乎。我們都知道類型擦除,並且Java不會放棄類型擦除併爲類型參數添加運行時類型。所以只要你知道你在做什麼,你就可以使用原始類型並自由投射。

+1

是的,你可以創建一個未知的通用ArrayList,但是你不能添加一些東西,這是我的問題發揮的地方。 – ars265

+0

這與ArrayList al = new ArrayList ();'有什麼區別? – newacct

+1

@newacct大概是,有一個帶外協議,在某些時候,列表可以安全地(通過應用程序邏輯)轉換爲'ArrayList ',並且向其中添加一個'X'對象。擦除,演員和添加都不是問題。具體化是另一回事。 – irreputable

4

你可以使用ArrayList<Object>,你可以add()任何東西。

+1

是的,但之後它們是對象類型的,不再是未知類型。這將工作,只要添加,但返回鑄造的對象ArrayList。用戶然後將不得不將每一個回來。現在,從1.4開始,我相信,Java確實保留了它們的子類中的額外數據,但並不能滿足我需要的。 – ars265

+0

@ ars265:但是由於在編譯時你不知道類型,所以無論如何你必須將它拋棄 – newacct

+0

@newacct:這是真的,但我正在開發一個框架,以便框架的用戶可以收到結果。我正在尋找一些有點不同的東西。我最終爲環境構建了一個linq類類。 – ars265

相關問題