Wie wirken sich unterschiedliche Aufbewahrungsrichtlinien auf meine Anmerkungen aus?

175

Kann jemand die praktischen Unterschiede zwischen den in einer klaren Art und Weise erklärt java.lang.annotation.RetentionPolicyKonstanten SOURCE, CLASSund RUNTIME?

Ich bin mir auch nicht ganz sicher, was der Ausdruck "Annotation beibehalten" bedeutet.

xdevel2000
quelle
5
Die Dokumentation ( java.sun.com/j2se/1.5.0/docs/api/java/lang/annotation/… ) ist sehr klar.
True Soft
Ja, ich habe bereits gelesen, aber ich verstehe in der Praxis nicht, wie es funktioniert. In der Tat, wenn ich 'diesen Satz' versuche: "" "" Anmerkungen müssen vom Compiler in der Klassendatei aufgezeichnet werden, müssen aber zur Laufzeit nicht von der VM beibehalten werden. "" "und öffnen Sie dann eine dekompilierte Klasse, in der ich eine Anmerkung mit der Aufbewahrungsrichtlinie KLASSE
eingefügt habe.
2
Dann scheint Ihr Dekompiler keine Anmerkungen zu unterstützen. jd-gui funktioniert gut.
musiKk
Danke das problem war mein decompiler dj und jad ... jd-gui zeig es mir !!
xdevel2000

Antworten:

209
  • RetentionPolicy.SOURCE: Während des Kompilierens verwerfen. Diese Anmerkungen machen nach Abschluss der Kompilierung keinen Sinn, daher werden sie nicht in den Bytecode geschrieben.
    Beispiel : @Override,@SuppressWarnings

  • RetentionPolicy.CLASS: Beim Laden der Klasse verwerfen. Nützlich bei der Nachbearbeitung auf Bytecode-Ebene. Etwas überraschend ist dies die Standardeinstellung.

  • RetentionPolicy.RUNTIME: Nicht wegwerfen. Die Anmerkung sollte zur Laufzeit zur Reflexion verfügbar sein. Beispiel:@Deprecated

Quelle: Die alte URL ist jetzt tot hunter_meta und wurde durch hunter-meta-2-098036 ersetzt . Falls auch dies ausfällt, lade ich das Bild der Seite hoch.

Bild (Klicken Sie mit der rechten Maustaste und wählen Sie "Bild in neuem Tab / Fenster öffnen".) Screenshot der Oracle-Website

Favonius
quelle
1
danke für das Zitat, das interessanteste hier ist der Anwendungsfall fürRetentionPolicy.CLASS
Max
1
Können Sie erklären, warum RetentionPolicy.class interessant / überraschend die Standardeinstellung ist?
Sudocoder
1
@sudocoder - Siehe folgende Links: stackoverflow.com/a/5971247/373861 und stackoverflow.com/a/3849602/373861 . Ich glaube, diese spezielle Richtlinie wird für die Bytecode-Instrumentierung benötigt. Obwohl ich es selbst nie benutzt habe.
Favonius
Am Ende heißt es Im nächsten Artikel dieser Reihe werde ich zeigen, wie die Reflexionsfunktionen von Java verbessert wurden, damit Sie zur Laufzeit Anmerkungen erkennen können, und wie Sie mit dem Anmerkungsverarbeitungs-Tool "apt" Anmerkungen zur Erstellungszeit verwenden können. , wo ist dieser Artikel?
Sushant
@Sushant: Nun, ich bin mir nicht sicher, wo es ist :). Obwohl aptveraltet, lesen Sie bitte diese docs.oracle.com/javase/7/docs/technotes/guides/apt/… . Zum Erkennen von Anmerkungen mithilfe von Reflektion gibt es im Internet mehrere Tutorials. Sie können beginnen, indem Sie java.lang.Class::getAnno*ähnliche Methoden in java.lang.reflect.Methodund untersuchen java.lang.reflect.Field.
Favonius
57

Nach Ihren Kommentaren zur Klassendekompilierung sollte dies meiner Meinung nach folgendermaßen funktionieren:

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

  • RetentionPolicy.CLASS: Erscheint in der dekompilierten Klasse, kann aber zur Laufzeit nicht mit Reflection with überprüft werden getAnnotations()

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

ewernli
quelle
Ja, das habe ich auch gedacht, aber in der dekompilierten Klasse ist nichts vorhanden !!! und deshalb bin ich verwirrt ... Ich werde versuchen, die Klassendatei mit dem Javap-Tool zu
überprüfen
javap gibt nichts zurück wo werden sie dann abgelegt?
xdevel2000
1
Gibt es einen Anwendungsfall für RetentionPolicy.CLASS?
Rahul
20

Minimal lauffähiges 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 javapbeobachten wir, dass die mit Retention.CLASSAnmerkungen versehene Klasse ein RuntimeInvisible- Klassenattribut erhält :

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

Während die Retention.RUNTIMEAnnotation ein RuntimeVisible- Klassenattribut erhält :

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

und die Runtime.SOURCEAnnotation .classerhält keine Annotation.

Beispiele auf GitHub, mit denen Sie spielen können.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
quelle
Irgendeine Idee, was Runtime.SOURCE und Runtime.CLASS nützen?
Praveen Kamath
@PraveenKamath Ich kenne kein Beispiel, wo sie nützlich sind. Wahrscheinlich passiert es nur, wenn Sie JVM-Sachen auf niedrigerer Ebene machen, die die meisten Entwickler niemals machen. Lassen Sie mich wissen, wenn Sie eine Bewerbung für sie finden.
Ciro Santilli 3 冠状 病 六四 事件 3
5

Aufbewahrungsrichtlinie: Eine Aufbewahrungsrichtlinie bestimmt, an welchem ​​Punkt eine Anmerkung verworfen wird. Es wird mithilfe der in Java integrierten Anmerkungen angegeben: @Retention[Info]

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
quelle
0
  • KLASSE : Anmerkungen müssen vom Compiler in der Klassendatei aufgezeichnet werden, müssen jedoch zur Laufzeit nicht von der VM beibehalten werden.
  • RUNTIME : Anmerkungen müssen vom Compiler in der Klassendatei aufgezeichnet und zur Laufzeit von der VM aufbewahrt werden, damit sie reflektiert gelesen werden können.
  • QUELLE : Anmerkungen sind vom Compiler zu verwerfen.

Oracle Doc

Michael Wong
quelle