it-swarm.com.de

RetentionPolicy CLASS vs. RUNTIME

Was ist der praktische Unterschied zwischen RetentionPolicy.CLASS und RetentionPolicy.RUNTIME?

Es sieht so aus, als ob beide im Bytecode aufgezeichnet werden und auf beide ohnehin zur Laufzeit zugegriffen werden kann.

41
Dima

auf beide kann ohnehin zur Laufzeit zugegriffen werden.

Das ist nicht das, was der javadoc sagt:

RUNTIME: Anmerkungen werden vom Compiler in der Klassendatei aufgezeichnet und von VM zur Laufzeit beibehalten, sodass sie reflektierend gelesen werden können .

CLASS: Anmerkungen werden vom Compiler in der Klassendatei aufgezeichnet, aber muss nicht zur Laufzeit von VM aufbewahrt werden .

In der Praxis sind mir keine Anwendungsfälle für CLASS bekannt. Es wäre nur nützlich, wenn Sie den Bytecode programmgesteuert lesen möchten, im Gegensatz zur Verwendung der Classloader-API. Dies ist jedoch ein sehr spezieller Fall, und ich weiß nicht, warum Sie nicht einfach RUNTIME verwenden.

Ironischerweise ist CLASS das Standardverhalten.

51
skaffman

Es sieht so aus, als ob beide im Bytecode aufgezeichnet werden und auf beide ohnehin zur Laufzeit zugegriffen werden kann.

Falsch für grundlegende integrierte Anmerkungsschnittstellen wie getAnnotations. Z.B.:

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

die einzige Möglichkeit, eine RetentionPolicy.CLASS-Anmerkung zu beobachten, besteht darin, einen Bytecode-Parser zu verwenden.

Ein weiterer Unterschied besteht darin, dass die mit Retention.CLASS annotierte Klasse ein RuntimeInvisible class-Attribut erhält, während Retention.RUNTIME-Anmerkungen ein RuntimeVisible class-Attribut erhalten. Dies kann mit javap beobachtet werden.

Beispiele auf GitHub zum Spielen.

Anmerkungen mit der Aufbewahrungsrichtlinie CLASS und RUNTIME sind über den Bytecode der Klasse zugänglich. Wir müssen eine Bytecode-Manipulationsbibliothek (z. B. ASM) verwenden, um auf die im Bytecode verfügbaren Annotationen zuzugreifen. 

Einfaches Beispiel hier - http://bethecoder.com/applications/tutorials/Java/annotations/class-and-runtime-retention-policy.html

0
yoAlex5