3

I have been searching for a few days about the Reflection API in Java. I want to get all the objects from a Collection class variable inside a passed object.

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);
    }
}
rgettman
  • 176,041
  • 30
  • 275
  • 357
Rahul Thachilath
  • 363
  • 3
  • 16
  • 2
    Why do you want to use reflection? Why simple polymorphism is not enough? – Taky Sep 23 '13 at 17:19
  • With your current code, it's not enough to show that S could be a collection. Have a look at http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html to see how to constrain the type of S. – brimble2010 Sep 23 '13 at 17:21
  • S is just any object i want to fetch every fields including collection classes with their values. – Rahul Thachilath Sep 23 '13 at 17:25
  • by "collection" do you mean `Collection` or do you include array and `Map` instances? If `Map` is included, do you want the keys as well as the values? You need to provide clearer requirements. – John B Sep 23 '13 at 17:28
  • What is the value of `targetMethodName`? Just using `iterator` or `toArray` might be a better idea. – Bernhard Barker Sep 23 '13 at 17:30
  • targetMethodName is just name of the getter of the current field by which i will get the value of the current field. – Rahul Thachilath Sep 23 '13 at 17:33
  • What is the **value** of `targetMethodName`? i.e. what's `source` and what motivated the expression you are assigning to `targetMethodName`? – Bernhard Barker Sep 23 '13 at 17:41
  • FYI, there is no reason to try to find a getter method when you can just use `Field.get`: http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Field.html#get(java.lang.Object) – John B Sep 23 '13 at 17:41

2 Answers2

6

I think the problem here is that ret could be any type of Collection: List, Set, Map, Array, custom class that implements Collection. A List could be ArrayList, LinkedList or any other type of List implementation. Getting the contents of the List via reflection would not work. What I suggest is that you support certain collection types as follows:

 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)
     ...

Then you can work with the elements in the array.

John B
  • 32,493
  • 6
  • 77
  • 98
5

Collection implement the Iterable interface, so you can travel through all items in the collection and get them.

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
    }
}
Casper Ngo
  • 343
  • 2
  • 8