202 votes

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

Quelqu'un peut-il expliquer de manière claire les différences pratiques entre la java.lang.annotation.RetentionPolicy constantes SOURCE , CLASS y RUNTIME ?

Je ne sais pas non plus exactement ce que signifie l'expression "conserver les annotations".

232voto

Favonius Points 9008
  • RetentionPolicy.SOURCE : Rejeter au cours de la la compilation. Ces annotations ne sont pas n'ont plus de sens une fois la compilation terminée terminée, elles ne sont donc pas écrites dans le bytecode.
    Ejemplo: @Override , @SuppressWarnings

  • RetentionPolicy.CLASS : Rejeter pendant chargement de la classe. Utile lorsque l'on effectue des post-traitement au niveau du bytecode. De manière assez surprenante, il s'agit de l'option par défaut.

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

Source : L'ancien URL est maintenant mort hunter_meta et remplacée par chasseur-meta-2-098036 . En cas de panne, je télécharge l'image de la page.

Image (Cliquer avec le bouton droit de la souris et sélectionner "Ouvrir l'image dans un nouvel onglet ou une nouvelle fenêtre") Screenshot of Oracle website

70voto

ewernli Points 23180

D'après vos commentaires sur la décompilation des classes, 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é à l'exécution avec la réflexion avec getAnnotations()

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

22voto

Ciro Santilli Points 3341

Exemple minimal exécutable

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 du bytecode : utiliser javap nous observons que le Retention.CLASS obtient une classe annotée RuntimeInvisible attribut de classe :

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

alors que Retention.RUNTIME obtient une annotation RuntimeVisible (temps d'exécution visible) attribut de classe :

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

y el Runtime.SOURCE annoté .class ne reçoit aucune annotation.

Exemples sur GitHub pour que vous puissiez jouer avec.

10voto

wahid_cse Points 1762

Politique de conservation : Une politique de conservation détermine à quel moment une annotation est supprimée. Elle est spécifiée à l'aide des annotations intégrées de Java : @Retention [À propos]

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.

0voto

Bush Points 593

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X