如何使用泛型获取集合的内容?

时间:2011-03-13 11:55:55

标签: java generics collections

我从hibernate查询获取对象。然后我有字段列表,我必须在这个对象上调用其getter。所以在我调用这些getter之后(不依赖于我,所以我不知道它们返回了什么),我把这些对象放在一个数组Object []中。现在我正在迭代这些对象,其中一些又是包含其他对象的集合。 所以我检查对象是否是这样的集合

private static boolean isCollection(Object obj){
    Class clazz = obj.getClass();
    return Collection.class.isAssignableFrom(clazz) ||     
     Map.class.isAssignableFrom(clazz);
}

现在我需要做一些像:

 if(isCollection(object)){
       get subobjects from this collection();
       getDeclaredMethods of this type of object();
       do something with everyObject();
}

感谢有关如何制作此通用的所有帮助。哦,是的,这个方法正在检查Map,但一般来说,在我的情况下,不能返回map,只能返回set和list。

谢谢

编辑:我会在这里添加确切的代码以供参考,以防它不清楚

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);
    }

2 个答案:

答案 0 :(得分:2)

这正是Generics试图阻止的代码。泛型尝试在您的代码中承担散布if object.type == class的负担。看看这里,这只是一个介绍:

  

http://en.wikipedia.org/wiki/Generics_in_Java

由于你有一个集合对象,你可以这样做:

List<List<? extends Shape>>

这是为了声明一个列表列表,并且尽可能精确地确定那些内部列表包含哪种对象(我选择Shape作为示例,不知道您想要处理哪种对象)。您可以在此处找到该确切代码的说明:

  

http://download.oracle.com/javase/tutorial/extra/generics/methods.html

答案 1 :(得分:0)

因为泛型在编译时被擦除,所以根据定义,如果在编译时无法知道该类型,则它们不能用于确定对象的类型。不幸的是,如果没有更改任何代码可以提供可能是也可能不是集合的对象数组,确定其类型的唯一方法是手动检查返回的对象类型,就像您已经在做的那样。

更多信息:http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

P.S。:并不是说没有更有效的方式来做你正在做的事情。通过将您已经确定的那些对象转换为集合,您可以“做某事”而无需借助反射来获取声明的方法。但是,实际的确定不能与Generics一起使用。