使用Java Reflections查找Collection的元素类型?

时间:2012-06-08 09:10:02

标签: java

考虑以下Java代码:

public class Test
{
    private Foo< String, String > foo1;
    private Foo< Integer, Integer > foo2;
}

public class Foo< T, V >
{
    private Bar< V > bar;
    private T a;
}

public class Bar< T >
{
    @MyAnnotation
    private List< T > list;
}

首先,从名为'Test'的类开始,我以递归方式搜索所有字段,这些字段用'MyAnnotation'注释,其类型派生自'java.lang.Collection'。对于给定的示例,结果将是:

  • Test.foo1.bar.list
  • Test.foo2.bar.list

很明显,第一个只能为其元素取字符串,而第二个只能取整数。

我的问题是:查找使用“MyAnnotation”注释的所有Collection字段以及告诉其元素类型的最佳(最简单)方法是什么?

从类型java.lang.Collection中查找带注释的字段不是问题。但是,对于给定的示例,我们如何得到看起来像下一个的结果?

  • Test.foo1.bar.list&LT;字符串&gt;
  • Test.foo2.bar.list&LT;整数&gt;

我尝试了几种方法,总是将'Object'作为集合的元素类型而不是'String'。

我真的坚持这个。 非常感谢提前!

2 个答案:

答案 0 :(得分:8)

可能你可以尝试这样:

Field field = Test1.class.getField("list");

Type genericFieldType = field.getGenericType();

if(genericFieldType instanceof ParameterizedType){
    ParameterizedType aType = (ParameterizedType) genericFieldType;
    Type[] fieldArgTypes = aType.getActualTypeArguments();
    for(Type fieldArgType : fieldArgTypes){
        Class fieldArgClass = (Class) fieldArgType;
        System.out.println("fieldArgClass = " + fieldArgClass);
    }
}

这将返回fieldArgClass = java.lang.String

答案 1 :(得分:0)

由于Java的类型擦除,这是不可能的。编译时,泛型类型将被原始类型替换,结果如下:

public class Test
{
    private Foo foo1;
    private Foo foo2;
}

public class Foo
{
    private Bar bar;
    private Object a;
}

public class Bar
{
    @MyAnnotation
    private List list;
}

然后在您直接使用foo1foo2的地方填写实际类型。例如,以下代码:

Test test = new Test();
List<String> a = test.foo1.bar;
String b = a.get(0);
Integer b = test.foo2.a;

将被翻译为:

Test test = new Test();
// The generic type is erased here...
List a = test.foo1.bar;
// ...and a cast is added here
String b = (String) a.get(0);
Integer b = (Integer) test.foo2.a;

长话短说:你无法检索那种类型,因为它在编译时被丢弃了。