Siapa pun dapat menjelaskan dengan cara yang jelas perbedaan praktis antara java.lang.annotation.RetentionPolicy
konstanta SOURCE
, CLASS
dan RUNTIME
?
Saya juga tidak yakin apa arti frasa "mempertahankan anotasi".
Siapa pun dapat menjelaskan dengan cara yang jelas perbedaan praktis antara java.lang.annotation.RetentionPolicy
konstanta SOURCE
, CLASS
dan RUNTIME
?
Saya juga tidak yakin apa arti frasa "mempertahankan anotasi".
Jawaban:
RetentionPolicy.SOURCE
: Buang selama kompilasi. Anotasi ini tidak masuk akal setelah kompilasi selesai, sehingga tidak ditulis ke bytecode.
Contoh:@Override
,@SuppressWarnings
RetentionPolicy.CLASS
: Buang selama pemuatan kelas. Berguna saat melakukan bytecode-level post-processing. Agak mengherankan, ini adalah default.
RetentionPolicy.RUNTIME
: Jangan dibuang. Anotasi harus tersedia untuk refleksi saat runtime. Contoh:@Deprecated
Sumber:
URL lama sudah mati sekarang
hunter_meta dan diganti dengan hunter-meta-2-098036 . Seandainya ini turun, saya mengunggah gambar halaman.
Gambar (Klik Kanan dan Pilih 'Buka Gambar di Tab / Jendela Baru')
RetentionPolicy.CLASS
apt
sudah usang, lihat dokumen inis.oracle.com/javase/7/docs/technotes/guides/apt/… . Untuk menemukan anotasi menggunakan refleksi ada beberapa tutorial di internet. Anda dapat mulai dengan melihat java.lang.Class::getAnno*
dan metode serupa di dalam java.lang.reflect.Method
dan java.lang.reflect.Field
.
Menurut komentar Anda tentang dekompilasi kelas, berikut ini menurut saya cara kerjanya:
RetentionPolicy.SOURCE
: Tidak akan muncul di kelas yang didekompilasi
RetentionPolicy.CLASS
: Tampil di kelas yang didekompilasi, tetapi tidak dapat diperiksa pada saat run-time dengan refleksi dengan getAnnotations()
RetentionPolicy.RUNTIME
: Tampil di kelas yang didekompilasi, dan dapat diperiksa pada saat dijalankan dengan refleksi bersama getAnnotations()
Contoh runnable minimal
Tingkat bahasa :
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;
}
Level bytecode : menggunakan javap
kami amati bahwa Retention.CLASS
kelas yang diberi catatan mendapat atribut kelas RuntimeInvisible :
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
sementara Retention.RUNTIME
anotasi mendapat atribut kelas RuntimeVisible :
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
dan Runtime.SOURCE
anotasi .class
tidak mendapatkan anotasi.
Contoh di GitHub untuk Anda mainkan.
Kebijakan Retensi: Kebijakan retensi menentukan pada titik mana anotasi dibuang. Ini ditentukan menggunakan anotasi bawaan Java: @Retention
[Tentang]
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.