2015-01-21 7 views
8

Beim Zugriff auf Anmerkungen, die über Reflection auf einem Feld definiert sind (d. H. Mit der Methode getDeclaredAnnotations() : Annotation[]), garantiert die Java 6 oder 7-Spezifikation die Reihenfolge, in der die Anmerkungen zurückgegeben werden. Ich habe die relevanten Java-Dokumente untersucht, kann aber keine definitive Antwort finden.Java-Anmerkungen Reflektionsreihenfolge

+1

Ich habe mich das vor allem mit Java 8 @Repeatable gefragt –

+0

Ich fragte mich die gleiche Frage - ich konnte bisher keine klare Aussage finden. Gibt es Neuigkeiten zu diesem Thema? – mkurz

+1

@Adam Gent, @mkurz: zumindest für wiederholbare Annotationen gibt es einige klare Worte in der Spezifikation, ich habe sie zusammengefügt. Sie erlauben sogar einen Rückschluss auf die ursprüngliche Frage zu 'getDeclaredAnnotations()'. – Holger

Antwort

9

Das ist in der Tat ein bisschen unterspezifiziert. Beginnen wir mit dem Java 8 Merkmal wiederholbar Anmerkungen beginnen, da es einige Bits darüber sind:

JLS §9.7.5. Multiple Annotations of the Same Type:

Die implizit deklariert Anmerkung der Container Anmerkung und die mehrere Anmerkungen vom Typ T genannt wird, die in dem Zusammenhang erschienen sind die Basis Anmerkungen genannt. Die Elemente des Elements (array-typed) value der Containeranmerkung sind alle Basisanmerkungen in der Reihenfolge von links nach rechts, in der sie im Kontext auftraten.

So wird der Container die wiederholten Annotationen in Reihenfolge bereitstellen.

Zusätzlich ist die Dokumentation von AnnotatedElement angibt:

Für einen Aufruf von get[Declared]AnnotationsByType(Class <T>), die Reihenfolge von Anmerkungen, die auf ein Element direkt oder indirekt vorhanden sind E als wenn indirekt vorliegenden Annotationen auf E berechnet wird, sind direkt an E anstatt ihrer Containeranmerkung in der Reihenfolge, in der sie im Wertelement der Containeranmerkung angezeigt werden, vorhanden.

diese beiden zusammen Einlochen, impliziert dies, dass wiederholte Anmerkungen wie @Foo(1) @Foo(2) @Foo(3) gespeichert sind, wie Sie @FooContainer({@Foo(1), @Foo(2), @Foo(3)}) und dieser geschrieben hatte, unabhängig davon, wie es ursprünglich erstellt wurde, wird durch getDeclaredAnnotations() wie direkt vorhanden Anmerkungen von dieser Reihenfolge behandelt werden.

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


Aber es ist eine andere Schlussfolgerung, die wir aus der Dokumentation von AnnotatedElement ziehen. 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 beim Schreiben von @Foo(1) @FooContainer({@Foo(2), @Foo(3)}) oder @FooContainer({@Foo(1), @Foo(2)}) @Foo(3) die Reihenfolge identisch mit den Elementen des Containers ist genau wie du es geschrieben hast .

Es ist interessant, how that is achieved:

Wenn Anmerkungen der Annotationstyp annotationClass sowohl direkt als auch indirekt präsent sein gefunden wird, dann getDeclaredAnnotations() die Reihenfolge der Elemente in der zurückgegebenen Array bestimmen genannt wird erhalten.

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.

Also die Antwort ist, ja, getDeclaredAnnotations() liefert die Annotationen in einer garantierten Reihenfolge, aber diese Informationen sind 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 das Ende ihres Lebens erreicht haben und sich nicht ändern, entspricht das beobachtete Verhalten ihrer Implementierung dem Verhalten, das bei Am wenigsten für Java 8, könnte genug sein, um sich darauf zu verlassen.

+1

Vielen Dank für Ihre gut präsentierte und umfassende Antwort. –

+0

Danke für diese detaillierte Antwort! Das ist die erste Aussage, die ich finden konnte, die klar und logisch sagt, in welcher Reihenfolge Annotationen über 'getDeclaredAnnotations() 'abgerufen werden - und ich habe schon einige Nachforschungen angestellt ... Vielen Dank! – mkurz

+0

Ich glaube nicht, dass Sie sich auf einen subtilen Hinweis verlassen können, der den Vertrag der Methode nicht direkt angibt, um die Reihenfolge einzuhalten. Wenn es der Fall war, dass jemand "vergessen hat, es in den Dokumenten zu erwähnen", wäre dies bereits behoben. Bis es in Stein gemeißelt ist, kann die Codierung gegen eine Annahme, dass es auch in Zukunft so bleiben wird, Ihre Annotationsfunktion zerstören. –