2010-06-24 13 views
115

Kann jemand in klarer Weise die praktischen Unterschiede zwischen den java.lang.annotation.RetentionPolicy Konstanten , CLASS und RUNTIME erklären?Wie wirken sich unterschiedliche Aufbewahrungsrichtlinien auf meine Anmerkungen aus?

Ich bin mir auch nicht genau sicher, was der Ausdruck "Halte Annotation" bedeutet.

+4

Die Dokumentation (http://java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/RetentionPolicy.html) ist sehr klar. –

+0

ja ich lese schon, aber ich verstehe in der Praxis nicht, wie es funktioniert. In der Tat, wenn ich 'diese Phrase' versuche: "" Anmerkungen werden in der Klassendatei vom Compiler aufgezeichnet, müssen aber nicht zur Laufzeit von der VM gespeichert werden."" " und öffnen Sie dann eine dekompilierte Klasse, wo ich eine Annotation mit Aufbewahrungsrichtlinie CLASS Ich finde nichts ... – xdevel2000

+2

Dann scheint Ihr Decompiler keine Anmerkungen unterstützt. Jd-gui funktioniert gut. – musiKk

Antwort

136
  • RetentionPolicy.SOURCE: Verwerfen während der Kompilierung. Diese Anmerkungen machen keinen Sinn nachdem die Kompilierung abgeschlossen hat, so dass sie nicht in Bytecode geschrieben werden.
    Beispiel: @Override, @SuppressWarnings

  • RetentionPolicy.CLASS: Verwerfen während Klasse Last. Nützlich, wenn Postcodeverarbeitung auf Bytecodeebene ausgeführt wird. Etwas überraschend, das ist der Standard.

  • RetentionPolicy.RUNTIME: Nicht verwerfen. Die Annotation sollte zur Laufzeit zur Reflektion verfügbar sein. Beispiel: @Deprecated

Quelle: Die alte URL jetzt mit hunter-meta-2-098036 hunter_meta und ersetzt tot ist. Falls dies auch nicht funktioniert, lade ich das Bild der Seite hoch.

Image (Rechtsklick und wählen Sie 'Bild öffnen in neuem Tab/Fenster') enter image description here

+1

danke für das Zitat, das interessanteste hier ist der Anwendungsfall für 'RetentionPolicy.CLASS' – Max

+1

können Sie erklären, warum RetentionPolicy.class interessant/überraschend ist Standard? – sudocoder

+1

@sudcoder - Siehe diese Links: http://StackOverflow.com/a/5971247/373861 und http://StackOverflow.com/A/3849602/373861.Ich glaube, dass diese spezielle Richtlinie für Bytecode Instrumentierung benötigt wird. Obwohl ich es nie selbst benutzt habe – Favonius

34

Nach Ihre Kommentare zu Klasse Dekompilierung, hier ist, wie ich denke, es sollte funktionieren:

  • RetentionPolicy.SOURCE: Wird nicht in der dekompilierten Klasse erscheinen

  • RetentionPolicy.CLASS: erscheint in der dekompiliert Klasse, kann aber nicht mit Reflexion mit getAnnotations()

  • RetentionPolicy.RUNTIME zur Laufzeit überprüft werden: Erscheint in der dekompilierten-Klasse und kann mit Reflexion mit getAnnotations()

+0

Ja auch ich dachte, aber in der dekompilierten Klasse ist nichts vorhanden !! ! und deshalb bin ich verwirrt ... ich werde versuchen, die klasse-datei mit dem javap-tool zu überprüfen – xdevel2000

+0

javap gibt nichts zurück wo sind dann gesetzt? – xdevel2000

+0

Kurz und gut, und genau das, was ich gesucht habe. – Matt

13

zur Laufzeit überprüft werden minimal runnable Beispiel

Sprachniveau:

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

Bytecode Ebene: mit javap wir beobachten, dass die Retention.CLASS kommentierte Klasse ein Attribut RuntimeInvisible Klasse bekommt:

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

während Retention.RUNTIME Anmerkung erhält eine RuntimeVisible Klasse Attribut:

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

und die Runtime.SOURCE Annotated .class wird keine Anmerkung erhalten.

Examples on GitHub für Sie mit zu spielen.

7

Aufbewahrungsrichtlinie: Eine Aufbewahrungsrichtlinie legt fest, wann eine Anmerkung verworfen wird.

Eine Aufbewahrungsrichtlinie wird mithilfe der integrierten Java-Anmerkungen festgelegt: @Retention.

0

RetentionPolicy.SOURCE: Die Annotation wäre im Quellcode des Programms verfügbar, sie wäre weder in der .class-Datei noch zur Laufzeit verfügbar. Wird vom Compiler verwendet.
RetentionPolicy.CLASS: Die Annotation wäre in der .class-Datei, aber zur Laufzeit nicht verfügbar. Wird von Byte-Code-Manipulationswerkzeugen wie ASM verwendet, führen Sie die Änderungen RetentionPolicy.RUNTIME aus: Die Annotation wäre in der .class-Datei und Laufzeit verfügbar, zur Überprüfung über Java-Reflektion über getAnnotations().

Verwandte Themen