【问题标题】:How to change information of objects in a List with reflection?如何通过反射更改列表中对象的信息?
【发布时间】:2017-06-19 06:48:44
【问题描述】:

我想读取和操作列表字段中的信息。更具体地说,我想访问嵌套列表对象listedInnerClasses 和hashMappedInnerClasses 的getter 和setter。我几乎没有影响我的 observeAndReflect 方法中的对象。不知道以后会传入哪个Class。

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

我的日志输出给了我一些信息:

INFO [main] (Runner.java:136) - # Type: int getName: id getValue 0
INFO [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.ListedInnerClass@7bc1a03d, application.ListedInnerClass@70b0b186]
INFO [main] (Runner. java:139) - ## 我的列表:[application.ListedInnerClass@7bc1a03d, application.ListedInnerClass@70b0b186]
INFO [main] (Runner.java:136) - # Type: long getName: serialVersionUID getValue 8683452581122892189
...

但我无法访问列表中的信息。

据我了解,列表中的类型参数信息由于类型擦除而丢失。所以编译器确实知道有一个 List,但忘记了其中有 ListedInnerClass 类型的对象。我试图重新转换该对象,但总是遇到同样的问题:无法访问 getter 和 setter。

还有办法获取信息吗?

提前致谢!

【问题讨论】:

    标签: java reflection


    【解决方案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);
        }
    }
    

    【讨论】:

    • 只需使用 fieldType.isAsignableForm(Collection.class) 并转换为集合。在这种情况下,所有的 List、Set、Queue 实现都可以工作。
    • 非常感谢!我在脑子里把它搞砸了,但现在我很清楚了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 2022-06-14
    • 1970-01-01
    • 2018-04-11
    相关资源
    最近更新 更多