2010-05-12 46 views
1

我有一個arraylist,我需要在運行時指定類型。如何在運行時指定genric類型

ArrayList<String> alist = new ArrayList<String>(); 

我需要在運行時指定「字符串」類型。我怎樣才能做到這一點。 它不應該是靜態的。

+1

查看überSkeet's或Darren Gilroy的回答http://stackoverflow.com/questions/1127923/specifying-generic-collection-type-param-at-runtime-java-reflection – 2010-05-12 06:29:36

+0

「我需要指定類型」String「在運行時「 - 基本上你沒有,你需要解釋你正在試圖做更詳細的。 – 2010-05-12 07:01:57

+0

我不遵循這個問題。你是否試圖在編譯時不知道泛型參數的情況下創建'ArrayList <>'?對於靜態類型特徵沒有任何意義(擦除似乎不相關,順便說一句)。如果封閉的實例或方法定義了一個通用參數,那麼這可能是你想要的。 – 2010-05-12 11:58:24

回答

5

這是不可能的,因爲type erasure - 一個過程,其中編譯器刪除類或參數內的類型參數和類型參數相關的所有信息。

它只在編譯期間可用來檢查類型。

編輯:作爲解決您的問題的解決方法,您可以使用ArrayList<Object>這將允許您將任何類型添加到ArrayList。在這種情況下,您可以使用instanceof檢查類型並將其轉換爲具體類型。

1

你的意思是你想參數化用於創建ArrayList的類型?

public <T> List<T> interestingMethod(Class<T> type) { 
    List<T> aList = new ArrayList<T>(); 
    // do something interesting... 
    return aList; 
} 

薪火type參數只需要類型推斷,我覺得這個模式的雜牌組裝電腦,但它與Java的唯一途徑。由於其他人會指出,由於類型擦除,我們沒有運行時類型信息和泛型。

+0

這是什麼語法的意思:'公衆列表有趣的方法(類類型)'?我以前沒有遇到過單獨的類型參數(第一個「」)。 – Eric 2010-05-12 06:52:09

+0

這是因爲該方法是通用的,但它所屬的類不是通用的。在這種情況下,我們需要聲明泛型類型(以及對其的任何約束,如擴展或超級)。 – SteveD 2010-05-12 06:56:55

1

泛型類型參數未編譯到字節碼中,因此在運行時不可用。一個ArrayList < String>在運行時只是一個ArrayList。 您可以實現的最接近的功能是自己添加運行時檢查。例如,Collections類提供了一個decorator認爲正是這一點:

List l = Collections.checkedList(new ArrayList<String>(), String.class); 
l.add("Jave uses erasure"); 
l.add(14); 

如果列表簡單地創建爲ArrayList的< string>後,兩個加法會在運行時取得成功。但是,使用包裝器實現時,每個項目添加都會被驗證,所以第二個調用將導致ClassCastException。