Baris public static <T> java.util.@Nullable Optional<T> toJavaUtilditulis seperti ini, karena gaya yang biasa public static <T> @Nullable java.util.Optional<T> toJavaUtiltidak valid. Ini didefinisikan dalam JLS §9.7.4 :
Ini adalah kesalahan waktu kompilasi jika anotasi tipe T berlaku untuk tipe (atau bagian mana pun dari tipe) dalam konteks tipe, dan T berlaku dalam konteks tipe, dan anotasi tidak dapat diterima.
Sebagai contoh, asumsikan TA jenis penjelasan yang meta-dijelaskan dengan adil @Target(ElementType.TYPE_USE). Persyaratan @TA java.lang.Objectdan java.@TA lang.Objectilegal karena nama sederhana yang paling dekat dengan @TA diklasifikasikan sebagai nama paket. Di sisi lain, java.lang.@TA Objectitu legal.
Deklarasi tipe org.checkerframework.checker.nullness.qual@Nullableadalah:
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
Jadi itu berlaku untuk aturan ini.
Bahwa struktur ini tidak menghentikan eksekusi, karena paket java.utildan nama kelas Optionalterpecah, dapat dilihat ketika kita melihat kode yang dikompilasi menggunakan 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.Optionaladalah kelas lokal tempat saya menyalin kode Guava, untuk mendapatkan contoh minimal untuk de- / kompilasi)
Seperti yang Anda lihat, anotasi tidak ada lagi di sana. Ini hanya penanda untuk kompiler untuk mencegah peringatan ketika metode mengembalikan nol (dan petunjuk untuk pembaca kode sumber), tetapi itu tidak akan dimasukkan dalam kode yang dikompilasi.
Kesalahan kompiler ini juga berlaku untuk variabel seperti:
private @Nullable2 java.util.Optional<?> o;
Tetapi dapat diterima ketika anotasi tambahan mendapatkan tipe target ElementType.FIELD, seperti yang tertulis dalam klausa JLS yang sama:
Jika TA ditambahkan dengan meta-anotasi @Target(ElementType.FIELD), maka istilah @TA java.lang.Objecttersebut legal di lokasi yang merupakan deklarasi dan tipe konteks, seperti deklarasi lapangan @TA java.lang.Object f;. Di sini, @TA dianggap berlaku untuk deklarasi f (dan bukan untuk tipe java.lang.Object) karena TA berlaku dalam konteks deklarasi lapangan.
Nullablemereka bicarakan sepertinya adajavax.annotation, bukanjava.util.