4

考虑以下 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<字符串>
  • Test.foo2.bar.list<整数>

我尝试了几种方法,它们总是给我“对象”作为集合的元素类型,而不是“字符串”。

我真的坚持这一点。提前谢谢了!

4

2 回答 2

11

也许你可以这样尝试:

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

于 2012-06-08T09:20:59.150 回答
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;
}

foo1然后在您直接使用和的地方填充实际类型foo2。例如,下面的代码:

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;

长话短说:您无法检索该类型,因为它在编译时被丢弃。

于 2012-06-08T09:54:50.913 回答