Czy ktoś może wyjaśnić w jasny sposób praktycznych różnic między java.lang.annotation.RetentionPolicy
stałymi SOURCE
, CLASS
i RUNTIME
?
Nie jestem też do końca pewien, co oznacza wyrażenie „zachowanie adnotacji”.
Czy ktoś może wyjaśnić w jasny sposób praktycznych różnic między java.lang.annotation.RetentionPolicy
stałymi SOURCE
, CLASS
i RUNTIME
?
Nie jestem też do końca pewien, co oznacza wyrażenie „zachowanie adnotacji”.
Odpowiedzi:
RetentionPolicy.SOURCE
: Odrzuć podczas kompilacji. Te adnotacje nie mają żadnego sensu po zakończeniu kompilacji, więc nie są zapisywane w kodzie bajtowym.
Przykład:@Override
,@SuppressWarnings
RetentionPolicy.CLASS
: Odrzuć podczas wczytywania klasy. Przydatne podczas przetwarzania końcowego na poziomie kodu bajtowego. Nieco zaskakujące jest to ustawienie domyślne.
RetentionPolicy.RUNTIME
: Nie wyrzucaj. Adnotacja powinna być dostępna do refleksji w czasie wykonywania. Przykład:@Deprecated
Źródło:
stary adres URL jest teraz martwy
hunter_meta i zastąpiony przez hunter-meta-2-098036 . Na wypadek, gdyby to się zdarzyło, przesyłam obraz strony.
Obraz (kliknij prawym przyciskiem myszy i wybierz „Otwórz obraz w nowej karcie / oknie”)
RetentionPolicy.CLASS
apt
jest przestarzały, zapoznaj się z tym docs.oracle.com/javase/7/docs/technotes/guides/apt/… . W Internecie dostępnych jest wiele samouczków do odkrywania adnotacji za pomocą refleksji. Możesz zacząć od przyjrzenia się java.lang.Class::getAnno*
i podobnym metodom w java.lang.reflect.Method
i java.lang.reflect.Field
.
Zgodnie z twoimi komentarzami na temat dekompilacji klas, oto jak myślę, że powinno to działać:
RetentionPolicy.SOURCE
: Nie pojawi się w zdekompilowanej klasie
RetentionPolicy.CLASS
: Pojawiają się w zdekompilowanej klasie, ale nie można ich sprawdzić w czasie wykonywania za pomocą odbicia z getAnnotations()
RetentionPolicy.RUNTIME
: Pojawiają się w zdekompilowanej klasie i można je sprawdzić w czasie wykonywania za pomocą refleksji za pomocą getAnnotations()
Minimalny przykład do uruchomienia
Poziom języka :
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;
}
Poziom kodu bajtowego : używając javap
obserwujemy, że Retention.CLASS
klasa z adnotacjami otrzymuje atrybut klasy RuntimeInvisible :
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
podczas gdy Retention.RUNTIME
adnotacja pobiera atrybut klasy RuntimeVisible :
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
a Runtime.SOURCE
adnotacja .class
nie otrzymuje adnotacji.
Przykłady na GitHub, z którymi możesz się bawić.
Zasady przechowywania: zasady przechowywania określają, w którym momencie adnotacja jest odrzucana. Jest to określone za pomocą wbudowanych adnotacji Java: @Retention
[Informacje]
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.