บรรทัดpublic static <T> java.util.@Nullable Optional<T> toJavaUtilถูกเขียนเช่นนี้เนื่องจากสไตล์ปกติpublic static <T> @Nullable java.util.Optional<T> toJavaUtilไม่ถูกต้อง สิ่งนี้กำหนดไว้ในJLS §9.7.4 :
มันเป็นข้อผิดพลาดในการคอมไพล์เวลาหากการเพิ่มความคิดเห็นของประเภท T นำไปใช้กับประเภท (หรือส่วนใดส่วนหนึ่งของประเภท) ในบริบทประเภทและ T สามารถใช้งานได้ในบริบทประเภทและคำอธิบายประกอบไม่สามารถยอมรับได้
ตัวอย่างเช่นสมมติประเภทคำอธิบายประกอบ TA @Target(ElementType.TYPE_USE)ซึ่งเป็นอภิข้อเขียนที่มีเพียง ข้อกำหนด@TA java.lang.Objectและjava.@TA lang.Objectผิดกฎหมายเนื่องจากชื่อแบบง่ายที่ @TA ใกล้เคียงที่สุดถูกจัดประเภทเป็นชื่อแพ็คเกจ ในทางตรงกันข้ามjava.lang.@TA Objectเป็นเรื่องถูกกฎหมาย
การประกาศประเภทของorg.checkerframework.checker.nullness.qual@Nullableคือ:
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
ดังนั้นจึงใช้กับกฎนี้
โครงสร้างนี้ไม่ได้หยุดการทำงานเนื่องจากแพ็คเกจjava.utilและชื่อคลาสOptionalถูกแบ่งออกสามารถมองเห็นได้เมื่อเราดูรหัสที่คอมไพล์โดยใช้javap -c [compiled class name]:
class just.a.test.Main {
just.a.test.Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static <T> java.util.Optional<T> toJavaUtil(blub.Optional<T>);
Code:
0: aload_0
1: ifnonnull 8
4: aconst_null
5: goto 12
8: aload_0
9: invokevirtual #2 // Method blub/Optional.toJavaUtil:()Ljava/util/Optional;
12: areturn
}
( blub.Optionalเป็นคลาสท้องถิ่นที่ฉันคัดลอกรหัส Guava เพื่อให้ได้ตัวอย่างน้อยที่สุดในการกำจัด / คอมไพล์)
อย่างที่คุณเห็นคำอธิบายประกอบจะไม่มีอยู่อีกต่อไป มันเป็นเพียงเครื่องหมายสำหรับคอมไพเลอร์เพื่อป้องกันการเตือนเมื่อเมธอดส่งคืน null (และคำใบ้สำหรับตัวอ่านซอร์สโค้ด) แต่จะไม่รวมอยู่ในโค้ดที่คอมไพล์
ข้อผิดพลาดของคอมไพเลอร์นี้ยังนำไปใช้กับตัวแปรเช่น:
private @Nullable2 java.util.Optional<?> o;
แต่สามารถยอมรับได้เมื่อคำอธิบายประกอบเพิ่มประเภทเป้าหมาย ElementType.FIELDตามที่เขียนไว้ในข้อ JLS เดียวกัน:
หาก TA ยังเป็นอภิกำกับด้วย@Target(ElementType.FIELD)แล้วคำว่าเป็นกฎหมายในสถานที่ซึ่งมีทั้งการประกาศและประเภทบริบทเช่นการประกาศเขต@TA java.lang.Object @TA java.lang.Object f;ที่นี่ @TA จะถือว่ามีผลบังคับใช้กับการประกาศ f (และไม่ใช้กับประเภท java.lang.Object) เนื่องจาก TA ใช้งานได้ในบริบทการประกาศฟิลด์
Nullableพวกเขากำลังพูดถึงดูเหมือนว่าจะมีในไม่javax.annotationjava.util