Java-Anmerkungen Reflektionsreihenfolge

8

Beim Zugriff auf Anmerkungen, die über Reflection in einem Feld definiert sind (d. h. mit der getDeclaredAnnotations() : Annotation[] -Methode), gibt die Java 6 oder 7-Spezifikation Gewähr für die Reihenfolge, in der die Anmerkungen zurückgegeben werden. Ich habe die relevanten Java-Dokumente untersucht, kann aber keine definitive Antwort finden.

    
Giles Thompson 21.01.2015, 12:18
quelle

1 Antwort

9

Das ist in der Tat ein bisschen unterspezifiziert. Beginnen wir mit der Java 8-Funktion der wiederholbaren Annotationen, da einige Bits dazu gehören:

JLS §9.7.5. Mehrere Anmerkungen desselben Typs :

  

Die implizit deklarierte Annotation wird als -Containerannotation bezeichnet, und die mehreren Annotationen vom Typ T , die im Kontext auftraten, werden als Basisannotationen bezeichnet. Die Elemente des (array-typed) value -Elements der Containeranmerkung sind alle Basisanmerkungen in der Reihenfolge von links nach rechts, in der sie im Kontext auftraten.

Der Container wird also die wiederholten Annotationen der Reihe nach bereitstellen.

Zusätzlich wird in der Dokumentation von AnnotatedElement angegeben :

  

Bei einem Aufruf von get[Declared]AnnotationsByType( Class < T >) wird die Reihenfolge der Annotationen, die direkt oder indirekt auf einem Element E vorhanden sind, berechnet, als ob indirekt vorhandene Annotationen auf E direkt sind Sie werden in E anstelle ihrer Containeranmerkung in der Reihenfolge angezeigt, in der sie im Wertelement der Containeranmerkung angezeigt werden.

Wenn Sie diese beiden zusammenfügen, bedeutet dies, dass wiederholte Annotationen wie @Foo(1) @Foo(2) @Foo(3) so gespeichert werden, wie Sie @FooContainer({@Foo(1), @Foo(2), @Foo(3)}) geschrieben haben, und letztere, unabhängig davon, wie sie ursprünglich erstellt wurde, werden von getDeclaredAnnotations() wie direkt vorhandene Annotationen von diese Reihenfolge.

Die Antwort für wiederholte Annotationen ist also, dass die Reihenfolge die "von links nach rechts" Reihenfolge ist, in der sie erschienen sind.

Aber es gibt eine andere Schlussfolgerung, die wir aus der Dokumentation von AnnotatedElement ziehen können. Da angegeben wird, dass die Reihenfolge der Annotationen so berechnet wird, als wären indirekt vorhandene Annotationen direkt anstelle der Annotation des Containers vorhanden, bedeutet dies, dass, wenn Sie @Foo(1) @FooContainer({@Foo(2), @Foo(3)}) oder @FooContainer({@Foo(1), @Foo(2)}) @Foo(3) schreiben, die Reihenfolge identisch mit den Elementen von container wird es genauso ersetzen wie du @Foo(1) @Foo(2) @Foo(3) geschrieben hast.

Es ist interessant, wie das ist erreicht :

  

Wenn Annotationen des Anmerkungstyps annotationClass sowohl direkt als auch indirekt vorhanden sind, wird getDeclaredAnnotations() aufgerufen, um die Reihenfolge der Elemente im zurückgegebenen Array zu bestimmen.

Dieser Implementierungshinweis ist der erste Indikator in der gesamten Dokumentation, dass getDeclaredAnnotations() eine zuverlässige Reihenfolge hat. Es wird verwendet, um die Reihenfolge zu bestimmen, die erforderlich ist, um den oben beschriebenen Vertrag zu erfüllen.

Die Antwort ist also, ja, getDeclaredAnnotations() liefert die Annotationen in einer garantierten Reihenfolge, aber diese Information ist nicht direkt an die Dokumentation der Methode selbst angehängt.

Dies ist aus der Java-8-Dokumentation abgeleitet, aber da Java 6 und 7 jetzt ihr Lebensende erreicht haben und sich nicht ändern werden, entspricht das beobachtete Verhalten ihrer Implementierung dem zumindest garantierten Verhalten für Java 8, könnte ausreichen, sich darauf zu verlassen.

    
Holger 13.05.2015, 18:24
quelle

Tags und Links