Frage

Wie es scheint getAnnotatedParameterTypes() gibt ein Array von zurück AnnotatedTypes enthält rohe statt generische Typen.Zum Beispiel:

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

Was ist der Grund für die Meinungsverschiedenheit mit getGenericParameterTypes()?

War es hilfreich?

Lösung

Da ist ein Fehlerbericht dazu, und es wurde inzwischen behoben.

Es gibt einen Unterschied zwischen Method#getGenericParameterTypes() Und Method#getAnnotatedParameterTypes().

Ersteres gibt Garantien für die Typen, die es zurückgibt

Wenn ein formaler Parametertyp ein parametrisierter Typ ist, muss das dafür zurückgegebene Typobjekt die im Quellcode verwendeten tatsächlichen Typparameter genau widerspiegeln.

Wenn ein formaler Parametertyp eine Typvariable oder ein parametrisierter Typ ist, wird er erstellt.Andernfalls wird es behoben.

während letzteres nicht der Fall ist, zumindest nicht eindeutig:

Gibt ein Array von zurück AnnotatedType Objekte, die die Verwendung von Typen zur Angabe formaler Parametertypen der Methode/Konstruktor darstellen, die durch diese dargestellt werden Executable.

Davon müssen wir ausgehen getAnnotatedParameterTypes() gibt die gelöschten Typen zurück (obwohl dies möglicherweise nicht so beabsichtigt war).Die unbegrenzte Typvariable T wird gelöscht Object.Wenn du hättest <T extends Foo>, es würde gelöscht werden Foo.

Was die Kommentare zum Abrufen der Annotation aus einem Typargument in einem Methodenparameter betrifft, gibt es angesichts des oben Gesagten keine Möglichkeit.Man könnte meinen, dass es genauso funktioniert wie bei Feldern.

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;

welches druckt

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

Ich bin der festen Überzeugung, dass es sich um einen Fehler handelt, der behoben werden muss, und werde den oben verlinkten Fehlerbericht weiterverfolgen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top