如何从Java 8中的getAnnotatedParameterTypes()获取泛型类型信息? [英] How to get generic type information from getAnnotatedParameterTypes() in Java 8?

查看:1885
本文介绍了如何从Java 8中的getAnnotatedParameterTypes()获取泛型类型信息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看起来像 getAnnotatedParameterTypes()返回一个包含 AnnotatedType 的数组,它保存原始类型,而不是通用类型。例如:

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

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

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

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

//失败; annotatedType仅实现AnnotatedType
assertTrue(annotatedType instanceof AnnotatedTypeVariable);

//这也失败了; type是TypeVariable,而annotatedType.getType()是
// Object.class
assertEquals(type,annotatedType.getType());



$ b

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

解决方案

有一个关于这个bug的错误报告,并且它已经被修复。 p>

方法#getGenericParameterTypes() 方法#getAnnotatedParameterTypes()
$ b

前者保证返回的类型


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


如果一个形式参数类型是一个类型变量或一个参数化类型,则创建它

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


返回一个 AnnotatedType 对象的数组,这些对象表示使用
类型指定方法的形式参数类型/构造函数
代表这个可执行文件


假设 getAnnotatedParameterTypes() 返回擦除类型(尽管它可能没有这种意图)。无界类型变量 T 被擦除为 Object 。如果你有< T extends Foo> ,它将被清除为 Foo



至于注释,关于从方法参数中的类型参数获取注释,上面没有办法给出。人们会认为它的工作原理与字段一样。

  public static void main(String [] args)throws Exception {
Field field = Example.class.getField(field);
AnnotatedParameterizedType annotatedParameterizedType =(AnnotatedParameterizedType)字段
.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 {
}

公共列表< @Bar String>领域;

可以打印

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

我非常认为这是一个需要修复的错误,并且会跟随上面链接的错误报告。


It seems like getAnnotatedParameterTypes() returns an array of AnnotatedTypes holding raw, rather than generic, types. For example:

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());
}

What's the reason for the disagreement with getGenericParameterTypes()?

解决方案

There's a bug report about this, and it has since been fixed.

There's a difference between Method#getGenericParameterTypes() and Method#getAnnotatedParameterTypes().

The former makes guarantees about the types it returns

If a formal parameter type is a parameterized type, the Type object returned for it must accurately reflect the actual type parameters used in the source code.

If a formal parameter type is a type variable or a parameterized type, it is created. Otherwise, it is resolved.

while the latter doesn't, not clearly at least:

Returns an array of AnnotatedType objects that represent the use of types to specify formal parameter types of the method/constructor represented by this Executable.

We have to assume that getAnnotatedParameterTypes() returns the erased types (although it may not have been intended that way). The unbounded type variable T is erased to Object. If you had <T extends Foo>, it would be erased to Foo.

As for the comments, about getting the annotation from a type argument in a method parameter, there's no way given the above. One would think it works as it does for fields.

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;

which prints

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

I very much think it's a bug that needs fixing and will be following the bug report linked above.

这篇关于如何从Java 8中的getAnnotatedParameterTypes()获取泛型类型信息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆