是否可以使用反射[在Java中]获取Collection的元素(例如List)

时间:2017-01-14 20:40:44

标签: java generics reflection collections

我完成了我的研究,但如果有可能,我仍然无法调用它。这个问题听起来像一个特例。但是,我试图尽可能地概括它。

在Java中,我知道可以使用反射来公开对象的字段(比如x)。并且我知道可以更深入地暴露子对象的字段,例如x的字段。但是,当谈到通用对象时,这变得棘手。

为了更好地解释这一点,假设我们有以下两个简单的类:

package reflection;

import java.util.*;

public class Subject {

    public List<SomeUserDefinedObj> myListOfObj =
            new ArrayList<SomeUserDefinedObj>();

    public SomeUserDefinedObj singleObj = new SomeUserDefinedObj();

    public Subject(){
        myListOfObj.add(new SomeUserDefinedObj());
    }

}

package reflection;

public class SomeUserDefinedObj {

    public int x;

}

我们有以下测试类,它将通过反射检查Subject

package reflection;

import java.lang.reflect.*;

public class Test {

    public static void main(String[] args) {
        Subject subject = new Subject();

        Class<?> c = subject.getClass();   
        for (Field field:c.getDeclaredFields()){
            System.out.println("Field in " + c.getName() + ": " + field.getName());

            Class<?> nestedClass = field.getType();
            for (Field nestedField:nestedClass.getDeclaredFields()){
                System.out.println("\tField in " + nestedClass.getName() + ": " + nestedField.getName());
            }
        }        
    }
}

此测试的输出将是:

Field in reflection.Subject: myListOfObj
Field in reflection.Subject: singleObj
    Field in reflection.SomeUserDefinedObj: x

现在,我们可以看到检索单个对象的内容,但列表就好像是空的。我知道有很多方法可以使用对象本身的实例来获取列表的类型(从中可以迭代列表中的对象),例如来自subject的{​​{1}} Test。例如,我可以Object myInstance = field.get(subject);,我可以从中确定列表中元素的类型并迭代它们(测试和工作)。

然而,(在这里我的问题可能是具体的)我无法访问该实例(由于使用遗留代码设计阻止了这种奢侈)。所以,我试图仅使用反射的类对象来达到这个目标,例如来自c的{​​{1}}。我找到了一些资源,可以帮助我确定列表中元素的类型,例如herehere(我测试了它们并且它们有效)。但是,这个(第一个)并没有授予实际类型,因为类型可能是一个抽象类,(第二)我无法看到从那里获取列表元素信息的任何方式,无论如何类型是抽象与否。根据我的理解,检索给定此方法的类型只能保证它会返回使用列表而不是元素初始化的类型(甚至类型可能不正确,如所解释的那样)。

最后,根据我所说的所有情况,如果有可能实现这样的目标,那么我所阅读的资源不会强烈声明坚定(仅与反映的对象一起工作)对象的实际实例)。 那么,问题就变成了,是否可以在不使用反射访问实际实例的情况下检索Collection元素?

1 个答案:

答案 0 :(得分:0)

字段仅包含相应类的特定实例的值。

所以简单的答案是:没有实例,你不能访问字段的值(除非字段是状态)。

想象一下,一个类代表一个盒子的蓝图。当你现在对这样一个盒子的内容感兴趣时...你仍然需要一个真正的盒子来研究。

但是:当你能够在运行应用程序的同一个JVM中执行代码时...那么它可能以某种方式访问​​它们。您需要确定您所知道的其他对象是否可以包含您想要查看的那些框。