2017-06-19 70 views
0

我想阅读和处理列表字段中的信息。更具体地说,我想访问嵌套列表对象listedInnerClasses和hashMappedInnerClasses的getter和setter。我几乎没有影响我的observeAndReflect方法中的对象。我不知道将来会传入哪一类。如何用反射更改List中对象的信息?

public class ReflectMe { 

private int id; 
private long speed = 10; 
private SimpleInnerClass simpleInnerClass; 
private List<ListedInnerClass> listedInnerClasses; 
private HashMap<Long, HashMappedInnerClass> hashMappedInnerClass; 
// ... getter and setter 
} 

public class ListedInnerClass { 

private long id; 
private String foo = "bar"; 
// ... getter and setter 
} 

我填写一些东西来测试:

private void start() { 

    // reflectionTest 
    ReflectMe me = new ReflectMe(); 
    List<ListedInnerClass> listedInnerClasses = new ArrayList<ListedInnerClass>(); 
    ListedInnerClass aClass1 = new ListedInnerClass(); 
    ListedInnerClass aClass2 = new ListedInnerClass(); 
    aClass2.setFoo("bla"); 
    listedInnerClasses.add(aClass1); 
    listedInnerClasses.add(aClass2); 
    me.setListedInnerClasses(listedInnerClasses); 
    try { 
     observeAndReflect(me); 
    } catch(IllegalAccessException e) { 
     logger.error(e); 
    } 
} 

然后我就先访问。我开始与列表:

private void observeAndReflect(Object o) throws IllegalAccessException { 

    for (Field field : o.getClass().getDeclaredFields()) { 
     field.setAccessible(true); 
     Class<?> fieldType = field.getType(); 

     logger.info("# Type: " + fieldType.getName() + " getName: " + field.getName() + " getValue " + field.get(o)); 

     if (fieldType == List.class) { 
      // here I would like to change information of the lists objects 
      logger.info("## My List: " + field.get(o)); 
      observeAndReflect(field.get(o)); 
     } 
    } 
} 

我logoutput给我的一些信息:

INFO [主](Runner.java:136) - #类型:int的getName:ID的getValue 0
信息[main](Runner.java:136) - #Type:long getName:speed getValue 10
INFO [main](Runner.java:136) - #Type:application.SimpleInnerClass getName:simpleInnerClass getValue null
INFO [main ](Runner.java:136) - #类型:java.util.List getName:listedInnerClasses getValue [application.List edInnerClass @ 7bc1a03d,[email protected]]
INFO [主](Runner.java:139) - ##我的列表:[[email protected][email protected]]
INFO [主] (Runner.java:136) - #类型:长的getName:的serialVersionUID的getValue 8683452581122892189
...

但我不能以访问我的列表中的信息。

就我所知,由于类型擦除,来自列表的类型参数的信息会丢失。因此,编译器确实知道有一个List,但忘记了Type ListedInterclass中有对象。我尝试重新转换该对象,但始终以相同的问题结束:无法访问getter和setter。

还有一种方法可以访问这些信息吗?

在此先感谢!

回答

1

根据你的程序的逻辑,你需要不及格名单,但名单的项目:

if (fieldType == List.class) { 
    // here I would like to change information of the lists objects 
    logger.info("## My List: " + field.get(o)); 
    List items = (List) field.get(o) 
    for(Object item : items) { 
     observeAndReflect(item); 
    } 
} 
+1

只需使用fieldType.isAsignableForm(Collection.class)和转换为收藏。在这种情况下,所有List,Set,Queue实现都可以工作。 – alexey28

+0

非常感谢!我把它搞砸了,但现在对我来说很清楚。 – Sascha