Comment les différentes politiques de conservation affectent-elles mes annotations?

175

Quelqu'un peut -il expliquer de façon claire les différences pratiques entre les java.lang.annotation.RetentionPolicyconstantes SOURCE, CLASS, et RUNTIME?

Je ne sais pas non plus exactement ce que signifie l'expression «retenir l'annotation».

xdevel2000
la source
5
La documentation ( java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/… ) est très claire.
True Soft
oui j'ai déjà lu mais je ne comprends pas en pratique comment ça marche. En fait, si j'essaie 'cette phrase': "" "" Les annotations doivent être enregistrées dans le fichier de classe par le compilateur mais n'ont pas besoin d'être conservées par la VM au moment de l'exécution. "" "puis ouvrez une classe décompilée où je mets une annotation avec la politique de rétention CLASSE Je ne trouve rien ...
xdevel2000
2
Ensuite, votre décompilateur ne semble pas prendre en charge les annotations. jd-gui fonctionne très bien.
musiKk
Merci le problème était mon décompilateur dj et jad ... jd-gui me montre !!
xdevel2000

Réponses:

210
  • RetentionPolicy.SOURCE: Jeter pendant la compilation. Ces annotations n'ont aucun sens une fois la compilation terminée, elles ne sont donc pas écrites dans le bytecode.
    Exemple: @Override,@SuppressWarnings

  • RetentionPolicy.CLASS: Jeter pendant le chargement de la classe. Utile lors du post-traitement au niveau du bytecode. De manière assez surprenante, c'est la valeur par défaut.

  • RetentionPolicy.RUNTIME: Ne pas jeter. L'annotation doit être disponible pour réflexion au moment de l'exécution. Exemple:@Deprecated

Source: L'ancienne URL est maintenant morte hunter_meta et remplacée par hunter-meta-2-098036 . Au cas où même cela tombe en panne, je télécharge l'image de la page.

Image (clic droit et sélectionnez `` Ouvrir l'image dans un nouvel onglet / fenêtre '') Capture d'écran du site Web d'Oracle

Favonius
la source
1
merci pour la citation, le plus intéressant ici est le cas d'utilisation pourRetentionPolicy.CLASS
Max
2
pouvez-vous expliquer pourquoi RetentionPolicy.class est intéressant / étonnamment la valeur par défaut?
sudocoder
1
@sudocoder - Reportez-vous à ces liens: stackoverflow.com/a/5971247/373861 et stackoverflow.com/a/3849602/373861 . Je crois que cette politique particulière est nécessaire pour l'instrumentation de bytecode. Bien que je ne l'ai jamais utilisé moi-même.
Favonius
À la fin, il est dit Dans le prochain article de cette série, je montrerai comment les capacités de réflexion de Java ont été améliorées pour vous aider à découvrir les annotations au moment de l'exécution et comment l'outil de traitement des annotations "apt" vous permet d'utiliser les annotations au moment de la construction. , où est cet article?
Sushant
@Sushant: Eh bien, je ne sais pas où est-ce :). Bien qu'il aptsoit obsolète, reportez-vous à ce docs.oracle.com/javase/7/docs/technotes/guides/apt/… . Pour découvrir les annotations à l'aide de la réflexion, il existe plusieurs didacticiels sur Internet. Vous pouvez commencer par rechercher java.lang.Class::getAnno*des méthodes similaires dans java.lang.reflect.Methodet java.lang.reflect.Field.
Favonius le
57

D'après vos commentaires sur la décompilation de classe, voici comment je pense que cela devrait fonctionner:

  • RetentionPolicy.SOURCE: N'apparaîtra pas dans la classe décompilée

  • RetentionPolicy.CLASS: Apparaît dans la classe décompilée, mais ne peut pas être inspecté au moment de l'exécution avec une réflexion avec getAnnotations()

  • RetentionPolicy.RUNTIME: Apparaissent dans la classe décompilée et peuvent être inspectés au moment de l'exécution avec réflexion avec getAnnotations()

Ewernli
la source
Oui aussi je le pensais mais dans la classe décompilée rien n'est présent !!! et donc je suis confus ... je vais essayer d'inspecter le fichier de classe avec l'outil
javap
javap ne renvoie rien où sont mis alors?
xdevel2000
1
un cas d'utilisation de RetentionPolicy.CLASS?
Rahul
20

Exemple exécutable minimal

Niveau de langue :

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

Niveau Bytecode : en utilisant javapnous observons que la Retention.CLASSclasse annotée obtient un attribut de classe RuntimeInvisible :

#14 = Utf8               LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
  0: #14()

tandis que l' Retention.RUNTIMEannotation obtient un attribut de classe RuntimeVisible :

#14 = Utf8               LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
  0: #14()

et l' Runtime.SOURCEannoté .classn'obtient aucune annotation.

Exemples sur GitHub avec lesquels vous pouvez jouer.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
la source
Alors une idée de l'utilisation de Runtime.SOURCE et Runtime.CLASS?
Praveen Kamath
@PraveenKamath Je ne connais aucun exemple où ils sont utiles. Cela n'arrive probablement que si vous effectuez des tâches JVM de niveau inférieur que la plupart des développeurs ne font jamais. Faites-moi savoir si vous trouvez une application pour eux.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
5

Politique de rétention: une politique de rétention détermine à quel moment une annotation est supprimée. Il est spécifié à l'aide des annotations intégrées de Java: @Retention[About]

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.
Ferdous Wahid
la source
0
  • CLASSE : Les annotations doivent être enregistrées dans le fichier de classe par le compilateur mais n'ont pas besoin d'être conservées par la machine virtuelle au moment de l'exécution.
  • RUNTIME : Les annotations doivent être enregistrées dans le fichier de classe par le compilateur et conservées par la VM au moment de l'exécution, afin qu'elles puissent être lues de manière réfléchie.
  • SOURCE : Les annotations doivent être supprimées par le compilateur.

Doc Oracle

Michael Wong
la source