如何从Java 8中的getAnnotatedParameterTypes()获取泛型类型信息?

时间:2014-04-12 02:22:47

标签: java generics reflection java-8 type-annotation

似乎getAnnotatedParameterTypes()返回一个AnnotatedType数组,其中包含原始类型而非泛型类型。例如:

public <T> void genericMethod(T t) {
}

@Test
public void testAnnotatedTypes() throws ReflectiveOperationException {
    Method method = getClass().getMethod("genericMethod", Object.class);

    Type type = method.getGenericParameterTypes()[0];
    assertTrue(type instanceof TypeVariable);

    AnnotatedType annotatedType = method.getAnnotatedParameterTypes()[0];

    // This fails; annotatedType implements only AnnotatedType
    assertTrue(annotatedType instanceof AnnotatedTypeVariable);

    // This fails too; type is a TypeVariable while annotatedType.getType() is
    // Object.class
    assertEquals(type, annotatedType.getType());
}

getGenericParameterTypes()意见不一致的原因是什么?

1 个答案:

答案 0 :(得分:7)

有一个bug report about this,它已被修复。

Method#getGenericParameterTypes()Method#getAnnotatedParameterTypes()之间存在差异。

前者保证它返回的类型

  

如果形式参数类型是参数化类型,则为Type对象   返回它必须准确反映实际的类型参数   在源代码中使用。

     

如果形式参数类型是类型变量或参数化类型,   它被创造了。否则就解决了。

而后者没有,至少不清楚:

  

返回表示使用的AnnotatedType个对象的数组   用于指定方法/构造函数的形式参数类型的类型   由Executable代表。

我们必须假设getAnnotatedParameterTypes()返回已删除的类型(尽管它可能不是那样的)。无界类型变量T将被删除为Object。如果您有<T extends Foo>,则会将其删除为Foo

关于注释,关于从方法参数中的类型参数获取注释,没有办法给出上述内容。人们会认为它适用于田野。

public static void main(String[] args) throws Exception {
    Field field = Example.class.getField("field");
    AnnotatedParameterizedType annotatedParameterizedType = (AnnotatedParameterizedType) field
            .getAnnotatedType();

    System.out.println(annotatedParameterizedType
            .getAnnotatedActualTypeArguments()[0].getType());
    System.out.println(Arrays.toString(annotatedParameterizedType
            .getAnnotatedActualTypeArguments()[0].getAnnotations()));
}

@Retention(RetentionPolicy.RUNTIME)
@Target(value = { ElementType.TYPE_USE })
@interface Bar {
}

public List<@Bar String> field;

打印

class java.lang.String
[@com.example.Example$Bar()]

我非常认为这是一个需要修复的错误,并将遵循上面链接的错误报告。