web-dev-qa-db-fra.com

RétentionPolicy CLASS vs. RUNTIME

Quelle est la différence pratique entre RetentionPolicy.CLASS et RetentionPolicy.RUNTIME?

On dirait que les deux sont enregistrés dans le bytecode et que les deux sont accessibles de toute façon au moment de l'exécution.

41
Dima

les deux peuvent être accessibles au moment de l'exécution de toute façon.

Ce n'est pas ce que dit le javadoc :

RUNTIME: Les annotations doivent être enregistrées dans le fichier de classe par le compilateur et conservées par le VM au moment de l'exécution, afin qu'elles puissent être lues de manière réfléchie .

CLASS: Les annotations doivent être enregistrées dans le fichier de classe par le compilateur, mais n'a pas besoin d'être conservé par le VM au moment de l'exécution .

En pratique, je ne connais aucun cas d'utilisation de CLASS. Cela ne serait utile que si vous vouliez lire le bytecode par programme, par opposition à l'API classloader, mais c'est un cas très spécialisé, et je ne sais pas pourquoi vous n'utiliseriez pas simplement RUNTIME.

Ironiquement, CLASS est le comportement par défaut.

51
skaffman

On dirait que les deux sont enregistrés dans le bytecode et que les deux sont accessibles de toute façon au moment de l'exécution.

False pour les interfaces d'annotation intégrées de base telles que getAnnotations. Par exemple.:

import Java.lang.annotation.Retention;
import Java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.CLASS)
@interface RetentionClass {}

@Retention(RetentionPolicy.RUNTIME)
@interface RetentionRuntime {}

public static void main(String[] args) {
    @RetentionClass
    class C {}
    assert C.class.getAnnotations().length == 0;

    @RetentionRuntime
    class D {}
    assert D.class.getAnnotations().length == 1;
}

la seule façon d'observer une annotation RetentionPolicy.CLASS consiste donc à utiliser un analyseur de code intermédiaire.

Une autre différence est que la classe annotée Retention.CLASS obtient un attribut RuntimeInvisible class, tandis que les annotations Retention.RUNTIME obtiennent un attribut RuntimeVisible class. Ceci peut être observé avec javap.

Exemples sur GitHub pour vous permettre de jouer.

Les annotations avec la stratégie de rétention CLASS et RUNTIME sont accessibles à partir du code d'octet de classe. Nous devons utiliser une bibliothèque de manipulation de code octet (par exemple, ASM) pour accéder aux annotations disponibles en code octet. 

Exemple simple ici - http://bethecoder.com/applications/tutorials/Java/annotations/class-and-runtime-retention-policy.html

0
yoAlex5