2010-05-28 41 views
0

我想獲得對Collection中保存的Object類型的訪問權限。以下是何時以及爲什麼我想要這樣做的一個簡單例子。這甚至有可能嗎?獲取類集合上元素的類型信息

List<Address> addressList = new LinkedList<Address>(); 

Main.addElement(addressList); 

Class Main{ 
    public void addElement(Object inArgument){ 
     List<Object> argument = (List<Object>)inArgument; 
     argument.add(/* WOULD LIKE TO CREATE A NEW OBJECT OF THE APPROPRIATE TYPE 
         HERE, IN THIS CASE, IT WOULD BE OF TYPE: "Address" */); 
    } 
} 

回答

5

不,你不能做到這一點與目前執行Java的泛型。類型參數在編譯時被「擦除」。

通過反射,您可以確定方法參數和返回類型以及成員變量的類型參數信息,但在這種情況下無法幫助。

作爲一種實用的解決方法,大多數想要執行類似操作的API都將Class實例作爲第二個參數。例如:

public void addElement(Collection<T> c, Class<? extends T> clz) 
    throws Exception 
{ 
    Constructor<? extends T> ctor = clz.getConstructor(); 
    T el = ctor.newInstance(); 
    c.add(el); 
} 
+0

無賴。我想這是有道理的,因爲列表只是一個引用的集合。值得懷疑的是,應用程序不需要知道引用在運行時指向的對象的類型。 – 2010-05-29 01:22:40

3

由於泛型細節在運行時不可用,因此無法使用當前方法定義的方式執行此操作。另一種方法是這樣:

public <T> void addElement(List<T> inArgument, Class<? extends T> clazz){ 
    T t = clazz.newInstnace(); 
    inArgument.add(t); 
    // exception handling omitted for brevity 
} 

你再調用addElement這樣

addElement(addressList, Address.class); 

見JLS的泛型類型的詳細信息,以及類型擦除。在簡單地說,類型擦除是responsbible針對此行爲:在b==true

Vector<String> x = new Vector<String>(); 
Vector<Integer> y = new Vector<Integer>(); 
boolean b = x.getClass() == y.getClass(); 

結果。

0
argument.add(null); 

null是每一個引用類型的值:P

但嚴重的是,我不知道你爲什麼會想這樣做。這意味着你的類型有某種「默認」值,這對一般類型來說並不是這樣。

0

我不確定我是否理解你的問題,但我認爲「超級」關鍵字在這裏可能很有用。

List<Address> addressList = new LinkedList<Address>(); 
List<Object> stuffToSeeInWashington = new LinkedList<Object>(); 

Main.addWhiteHouse(addressList); 
Main.addWhiteHouse(stuffToSeeInWashington); 

Class Main{ 
    public void addWhiteHouse(List<? super Address> argument){ 
     Address whiteHouse = new Address("1600 Pennsylvania Ave"); 
     argument.add(whiteHouse) ; 
    } 
}