ทุกคนสามารถอธิบายในทางที่ชัดเจนแตกต่างในทางปฏิบัติระหว่างjava.lang.annotation.RetentionPolicy
ค่าคงที่SOURCE
, CLASS
และRUNTIME
?
ฉันก็ไม่แน่ใจเหมือนกันว่าวลี "การเก็บคำอธิบายประกอบ" หมายถึงอะไร
ทุกคนสามารถอธิบายในทางที่ชัดเจนแตกต่างในทางปฏิบัติระหว่างjava.lang.annotation.RetentionPolicy
ค่าคงที่SOURCE
, CLASS
และRUNTIME
?
ฉันก็ไม่แน่ใจเหมือนกันว่าวลี "การเก็บคำอธิบายประกอบ" หมายถึงอะไร
คำตอบ:
RetentionPolicy.SOURCE
: ทิ้งระหว่างการคอมไพล์ คำอธิบายประกอบเหล่านี้ไม่สมเหตุสมผลหลังจากคอมไพล์เสร็จสมบูรณ์ดังนั้นจึงไม่ได้เขียนลงใน bytecode
ตัวอย่าง:@Override
,@SuppressWarnings
RetentionPolicy.CLASS
: ทิ้งระหว่างการโหลดคลาส มีประโยชน์เมื่อทำการประมวลผลภายหลังระดับ bytecode ค่อนข้างน่าประหลาดใจนี่เป็นค่าเริ่มต้น
RetentionPolicy.RUNTIME
: อย่าทิ้ง คำอธิบายประกอบควรจะมีให้สำหรับการสะท้อนที่รันไทม์ ตัวอย่าง:@Deprecated
ที่มา:
URL ที่เก่าที่ตายแล้วในขณะนี้
hunter_metaและแทนที่ด้วยนักล่า meta-2-098036 ในกรณีที่สิ่งนี้เกิดขึ้นฉันกำลังอัปโหลดภาพของหน้า
รูปภาพ (คลิกขวาและเลือก 'เปิดภาพในแท็บ / หน้าต่างใหม่')
RetentionPolicy.CLASS
apt
จะเลิกใช้แล้วโปรดอ้างถึงdocs.oracle.com/javase/7/docs/technotes/guides/apt/นี้ สำหรับการค้นหาคำอธิบายประกอบโดยใช้การสะท้อนมีบทเรียนมากมายบนอินเทอร์เน็ต คุณสามารถเริ่มต้นด้วยการมองเข้าไปในjava.lang.Class::getAnno*
และวิธีการที่คล้ายกันในและjava.lang.reflect.Method
java.lang.reflect.Field
ตามความคิดเห็นของคุณเกี่ยวกับการแยกย่อยชั้นเรียนนี่คือวิธีที่ฉันคิดว่าควรจะทำงาน
RetentionPolicy.SOURCE
: จะไม่ปรากฏในคลาสที่ถอดรหัสแล้ว
RetentionPolicy.CLASS
: ปรากฏในคลาสที่ถอดรหัสแล้ว แต่ไม่สามารถตรวจสอบได้ในเวลาทำงานโดยมีการสะท้อนกลับ getAnnotations()
RetentionPolicy.RUNTIME
: ปรากฏในคลาสที่ถอดรหัสแล้วและสามารถตรวจสอบได้ในเวลาทำงานโดยมีการสะท้อนกลับด้วย getAnnotations()
ตัวอย่างที่เรียกใช้น้อยที่สุด
ระดับภาษา :
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 : การใช้javap
เราสังเกตว่าRetention.CLASS
คลาสที่ทำหมายเหตุประกอบไว้จะได้รับแอตทริบิวต์ของคลาสRuntimeInvisible :
#14 = Utf8 LRetentionClass;
[...]
RuntimeInvisibleAnnotations:
0: #14()
ขณะที่Retention.RUNTIME
คำอธิบายประกอบจะได้รับคุณลักษณะคลาสRuntimeVisible :
#14 = Utf8 LRetentionRuntime;
[...]
RuntimeVisibleAnnotations:
0: #14()
และRuntime.SOURCE
คำอธิบายประกอบ.class
จะไม่ได้รับการเพิ่มความคิดเห็นใด ๆ
ตัวอย่างบน GitHubเพื่อให้คุณเล่นด้วย
นโยบายการเก็บรักษา: นโยบายการเก็บรักษาจะเป็นตัวกำหนดว่าการยกเลิกหมายเหตุประกอบจะมีจุดใด มันถูกระบุโดยใช้คำอธิบายประกอบในตัวของ Java: @Retention
[เกี่ยวกับ]
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.