2015-01-21 12 views
8

Quando si accede ad Annotazioni definite su un campo tramite Reflection (vale a dire utilizzando il metodo getDeclaredAnnotations() : Annotation[]) la specifica Java 6 o 7 fornisce garanzie sull'ordine in cui vengono restituite le Annotazioni. Ho esaminato i documenti java pertinenti ma non riesco a trovare una risposta definitiva.Ordine di riflessione di annotazioni Java

+1

Mi sono chiesto questo in particolare con java 8 @ ripetibile –

+0

Mi stavo ponendo la stessa domanda - non ho trovato nessuna dichiarazione chiara finora. Qualche novità al riguardo? – mkurz

+1

@Adam Gent, @mkurz: almeno per le annotazioni ripetibili, ci sono alcune parole chiare all'interno della specifica, le ho assemblate insieme. Permettono persino una conclusione sulla domanda originale riguardante 'getDeclaredAnnotations()'. – Holger

risposta

9

Questo è davvero un po 'sottostimato. Cominciamo con la funzione Java 8 di annotazioni ripetibili in quanto vi sono alcuni pezzi su di esso:

JLS §9.7.5. Multiple Annotations of the Same Type:

L'annotazione implicitamente dichiarata è chiamato il contenitore di annotazione, e le molteplici annotazioni di tipo T che apparso nel contesto sono chiamate le annotazioni di base . Gli elementi dell'elemento value dell'annotazione del contenitore sono tutte le annotazioni di base nell'ordine da sinistra a destra in cui sono stati visualizzati nel contesto.

Quindi il contenitore fornirà le annotazioni ripetute in ordine.

Inoltre, la documentazione di AnnotatedElement specifica:

Per un'invocazione get[Declared]AnnotationsByType(Class <T>), dell'ordine di annotazioni che sono direttamente o indirettamente presente su un elemento E viene calcolato come annotazioni indirettamente presenti E sono direttamente presenti su E al posto dell'annotazione del contenitore, nell'ordine in cui appaiono nell'elemento valore dell'annotazione del contenitore.

Mettendo questi due insieme, ciò implica che le annotazioni ripete come @Foo(1) @Foo(2) @Foo(3) vengono memorizzati come avevi scritto @FooContainer({@Foo(1), @Foo(2), @Foo(3)}) e il secondo, a prescindere da come è stato originariamente creato, saranno trattati da getDeclaredAnnotations() come annotazioni direttamente presenti su questo ordine.

Quindi la risposta per le annotazioni ripetute è che l'ordine sarà "l'ordine da sinistra a destra in cui sono stati visualizzati".


Ma c'è un'altra conclusione che possiamo trarre dalla documentazione di AnnotatedElement. Poiché afferma che l'ordine delle annotazioni è calcolato come se le annotazioni presenti indirettamente siano direttamente presenti al posto dell'annotazione del contenitore, ciò implica che se si scrive @Foo(1) @FooContainer({@Foo(2), @Foo(3)}) o @FooContainer({@Foo(1), @Foo(2)}) @Foo(3), l'ordine sarà uguale a quello che gli elementi del contenitore sostituiranno proprio come hai scritto @Foo(1) @Foo(2) @Foo(3).

È interessante, how that is achieved:

Se annotazioni del tipo di annotazione annotationClass risultano direttamente o indirettamente presente, allora getDeclaredAnnotations() verrà chiamato per determinare l'ordine degli elementi dell'array restituito.

Questa nota di implementazione è il primo indicatore dell'intera documentazione che getDeclaredAnnotations() ha un ordine affidabile.Viene utilizzato per determinare l'ordine richiesto per soddisfare il contratto sopra descritto.

Quindi la risposta è sì, getDeclaredAnnotations() fornisce le annotazioni in un ordine garantito, ma tali informazioni non sono direttamente allegate alla documentazione del metodo stesso.

Questo è derivato dalla documentazione di Java 8, ma poiché Java 6 e 7 hanno raggiunto la fine del loro ciclo di vita ora e non cambieranno, il fatto che il comportamento osservato della loro implementazione corrisponda al comportamento garantito a almeno per Java 8, potrebbe essere sufficiente affidarsi a questo.

+1

Grazie mille per la tua risposta ben presentata e completa. –

+0

Grazie per questa risposta dettagliata! Questa è la prima affermazione che ho trovato e che dice in modo chiaro e logico in quale ordine vengono recuperate le annotazioni tramite 'getDeclaredAnnotations()' - e ho già fatto alcune ricerche ... Grazie mille! – mkurz

+0

Non penso che si possa fare affidamento su un sottile suggerimento che non specifica direttamente il contratto del metodo per mantenere l'ordine. Se è il caso che "qualcuno ha dimenticato di menzionarlo nei documenti", questo sarebbe già stato corretto. Fino a quando non viene impostato su pietra, la codifica contro il presupposto che rimarrà tale in futuro potrebbe rompere la funzionalità basata su annotazioni. –