Как получить общую информацию о типе от getAnnotatedParameterTypes() в Java 8?

Это похоже на 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 ответ

Решение

Об этом есть сообщение об ошибке, и с тех пор оно было исправлено.

Есть разница между 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()]

Я очень думаю, что это ошибка, которая нуждается в исправлении и будет следовать сообщению об ошибке, указанному выше.

Другие вопросы по тегам