2013-09-23 43 views
2

我一直在尋找關於Java中的Reflection API的幾天。 我想從一個Collection類變量中獲取所有對象在一個傳遞的對象中。使用反射從集合類中獲取對象

E.g.

public static <S>void getValue(S s)throws Exception 
{ 
    Field[] sourceFields = s.getClass().getDeclaredFields(); 
    for (Field sf : sourceFields) 
    { 
     boolean sa = sf.isAccessible(); 
     sf.setAccessible(true); 

     String targetMethodName = "get" + source.getName().substring(0, 1).toUpperCase() 
       + (source.getName().substring(1)); 
     Method m = s.getClass().getMethod(targetMethodName, null) ; 
     Object ret = m.invoke(s, new Object[] {}); 

     //ret 
     //check whether it is collection 
     //if yes 
     //get its generic type 
     Type type = f.getGenericType(); 

     //get all the objects inside it 

     sf.setAccessible(sa); 
    } 
} 
+2

爲什麼要使用反射?爲什麼簡單的多態性是不夠的? – Taky

+0

用你現在的代碼,這不足以證明S可能是一個集合。看看http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html看看如何限制S.的類型。 – brimble2010

+0

S只是任何對象我想要獲取包括集合類的每個字段與他們的價值觀。 –

回答

4

我覺得這裏的問題是,ret可以是任何類型的收藏:ListSetMapArray,自定義類實現集合。 A List可以是ArrayList,LinkedList或任何其他類型的List實現。通過反射獲取List的內容不起作用。我的建議是,你支持某些集合類型如下:

Object[] containedValues; 
if (ref instanceof Collection) 
    containedValues = ((Collection)ref).toArray(); 
else if (ref instanceof Map) 
    containedValues = ((Map)ref).values().toArray(); 
else if (ref instanceof Object[]) 
    containedValues = (Object[])ref; 
else if (ref instanceof SomeOtherCollectionTypeISupport) 
    ... 

然後你可以用數組中的元素工作。

+0

這段代碼是我最後一個選項,我希望儘可能使用最少的硬編碼。 –

+0

它確實從集合類變量「'」(即'implements集合')中說'',所以完全有可能大部分是不必要的。 – Dukeling

+0

你可能是對的,在OP使用'collection'而不是'Collection'的地方,我錯過了最初的'C'。 –

3

集合實現了Iterable接口,因此您可以遍歷集合中的所有項並獲取它們。

Object ref = // something 
if (ref instanceof Collection) { 
    Iterator items = ((Collection) ref).iterator(); 
    while (items != null && items.hasNext()) { 
     Object item = items.next(); 
    // Do what you want 
    } 
}