使用Java反射获取具体的接口字段类

时间:2014-08-26 10:21:59

标签: java reflection

我有一个具有接口作为成员的类

Class A {
    IProp property;
}

在运行时,我们使用一个实现IProp的具体类来分配属性。 说,

A a = new A();
a.property = new IPropImpl();

现在如果我有对象a,我会使用反射来获取字段:

Field[] fields = a.getDeclaredFields();

但是对于字段property,类型将返回为IProp。我想得到分配给它的具体类型。 (可能有多种具体类型。我想获得分配给该字段的那个。)

任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:3)

getDeclaredFields()(或java.lang.Class的任何其他方法)返回可用于的编译时数据 - 它无法根据特定数据返回数据您正在使用实例

您可以做的只是检索您持有的实例并查询其类型:

System.out.println(a.property.getClass());

编辑:

要解决这些评论,这也可以通过反思来完成,但仍然需要解决一个特定的实例:

for (Field f : a.getClass().getDeclaredFields()) {
    Class<?> cls = f.get(a).getClass();
    System.out.println
        (f.getName() + " is set with a concrete class of " + cls.getName());
}

答案 1 :(得分:2)

您可以在字段上使用instanceOf来测试哪个是实现。我担心直接这样做的唯一方法是将属性类型更改为实现,这不是你想要的。

代码如下:

IProp property = null;
try {
    property = (IProp) A.class.getDeclaredField("property").get(a);
} catch (IllegalArgumentException | IllegalAccessException
        | NoSuchFieldException | SecurityException e) {
    e.printStackTrace();
}
if(property instanceof IPropImpl){
    //do something
}else if(property instanceof IPropImpl2){
    //do something else
}

修改

如果您希望以编程方式获取已经实例化的特定接口的所有实现类,您可以使用Reflection library

进行此操作。
new Reflections("my.package").getSubTypesOf(MyInterface.class)

否则,如果您使用Eclipse,请单击界面名称IProp,然后按CTRL + T。它将显示工作区中接口的所有实现类。