2017-06-19 17 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