Qualcuno può spiegare in modo chiaro le differenze pratiche tra le java.lang.annotation.RetentionPolicy
costanti SOURCE
, CLASS
, e RUNTIME
?
Inoltre, non sono esattamente sicuro del significato della frase "conservazione delle annotazioni".
Qualcuno può spiegare in modo chiaro le differenze pratiche tra le java.lang.annotation.RetentionPolicy
costanti SOURCE
, CLASS
, e RUNTIME
?
Inoltre, non sono esattamente sicuro del significato della frase "conservazione delle annotazioni".
Risposte:
RetentionPolicy.SOURCE
: Scarta durante la compilazione. Queste annotazioni non hanno alcun senso dopo il completamento della compilazione, quindi non vengono scritte nel bytecode.
Esempio:@Override
,@SuppressWarnings
RetentionPolicy.CLASS
: Scarta durante il caricamento di classe. Utile quando si esegue la post-elaborazione a livello di codice. Un po 'sorprendentemente, questo è il valore predefinito.
RetentionPolicy.RUNTIME
: Non scartare. L'annotazione dovrebbe essere disponibile per la riflessione in fase di esecuzione. Esempio:@Deprecated
Fonte: ora
il vecchio URL è morto
hunter_meta e sostituito con hunter-meta-2-098036 . Nel caso anche in questo caso, sto caricando l'immagine della pagina.
Immagine (clic destro e selezionare "Apri immagine in una nuova scheda / finestra")
RetentionPolicy.CLASS
apt
sia deprecato, consultare questo docs.oracle.com/javase/7/docs/technotes/guides/apt/… . Per scoprire le annotazioni usando la riflessione ci sono più tutorial su Internet. Puoi iniziare esaminando java.lang.Class::getAnno*
e metodi simili in java.lang.reflect.Method
e java.lang.reflect.Field
.
Secondo i tuoi commenti sulla decompilazione di classe, ecco come penso che dovrebbe funzionare:
RetentionPolicy.SOURCE
: Non verrà visualizzato nella classe decompilata
RetentionPolicy.CLASS
: Appare nella classe decompilata, ma non può essere ispezionato in fase di esecuzione con la riflessione con getAnnotations()
RetentionPolicy.RUNTIME
: Appare nella classe decompilata e può essere ispezionato in fase di esecuzione con la riflessione con getAnnotations()
Esempio eseguibile minimo
Livello linguistico :
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.SOURCE)
@interface RetentionSource {}
@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}
@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}
public static void main(String[] args) {
@RetentionSource
class B {}
assert B.class.getAnnotations().length == 0;
@RetentionClass
class C {}
assert C.class.getAnnotations().length == 0;
@RetentionRuntime
class D {}
assert D.class.getAnnotations().length == 1;
}
Livello bytecode : usando javap
osserviamo che la Retention.CLASS
classe annotata ottiene un attributo di classe RuntimeInvisible :
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
mentre l' Retention.RUNTIME
annotazione ottiene un attributo di classe RuntimeVisible :
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
e l' Runtime.SOURCE
annotato .class
non ottiene alcuna annotazione.
Esempi su GitHub con cui giocare.
Criterio di conservazione: un criterio di conservazione determina in quale punto viene scartata un'annotazione. Viene specificato utilizzando le annotazioni integrate di Java: @Retention
[Informazioni]
1.SOURCE: annotation retained only in the source file and is discarded
during compilation.
2.CLASS: annotation stored in the .class file during compilation,
not available in the run time.
3.RUNTIME: annotation stored in the .class file and available in the run time.