Reputation: 1237
I get object from hibernate query. Then i have list of fields, whose getters i must invoke on this object. So after i invoke these getters (not depending on me, so i have no idea what they return), i put these objects in one array Object[]. Now i am iterating through these objects, some of which are again collections containing other objects. So i check if objects is collection like this
private static boolean isCollection(Object obj){
Class clazz = obj.getClass();
return Collection.class.isAssignableFrom(clazz) ||
Map.class.isAssignableFrom(clazz);
}
now i need to do somethinhg like:
if(isCollection(object)){
get subobjects from this collection();
getDeclaredMethods of this type of object();
do something with everyObject();
}
Appreciate all the help on how to make this generic. Oh and yes, this method is checking for a Map, but in general in my case, map can not be returned, only sets and lists.
Thank you
EDIT: I will add exact code here for reference in case it is not clear
Object[] objectRow = parseObject(hibernateObject);
for(Object field: objectRow){
get subobjects from this collection();
getDeclaredMethods of this type of object();
do something with everyObject();
}
public Object[] parseObject(Object mainObject) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException{
rowToReturn = new Object[fieldObjects.size()];
Method[] allMethods = mainObject.getClass().getMethods();
Method[] getters = findGetters(allMethods);
cutGetters(getters); // builds map so that we match getters with fields
for(FieldObject field: fieldObjects){
if(getterNameMethodMap.containsKey(field.getFinalFieldName())){
Method methodToInvoke = getterNameMethodMap.get(field.getFinalFieldName());
Object invokedObject = methodToInvoke.invoke(mainObject, (Object) null);
rowToReturn[field.getOrder()] = invokedObject; // put what ever it is that we got, into the final array
}
}
return rowToReturn;
}
private void cutGetters(Method[] getters){
getterNameMethodMap = new HashMap<String, Method>();
for(Method getter:getters){
String stringToGet = getter.getName().substring(4,getter.getName().length());
getterNameMethodMap.put(stringToGet, getter);
}
Upvotes: 2
Views: 303
Reputation: 4469
Because Generics are erased at compile-time, by definition they cannot be used to determine the type of an object if you cannot know that type at compile-time. Unfortunately, without changing whatever code is giving you the array of objects that may or may not be Collections, the only way to determine their type is to manually check the returned Objects' types like you are already doing.
Further info: http://docs.oracle.com/javase/tutorial/java/generics/erasure.html
P.S.: that's not to say there isn't a more efficient way of doing what you're doing. By casting those objects that you have already determined are Collections, you may be able to "do something" without resorting to reflection to get the declared methods. The actual determination, however, cannot be shortcut with Generics.
Upvotes: 0
Reputation: 23550
This is exactly the code Generics try to prevent. Generics try to take the burden of scattering if object.type == class
throughout your code from you. Have a look here, this is only an introduction:
Since you have a collection of collections of objects, you would do something like this:
List<List<? extends Shape>>
This is to declare a list of lists and also to be as precise as possible which kind of object those inner lists contain (I chose Shape just as an example, no idea which kind of objects you want to deal with). You can find the explanation for that exact code here:
http://download.oracle.com/javase/tutorial/extra/generics/methods.html
Upvotes: 2