Dòng public static <T> java.util.@Nullable Optional<T> toJavaUtilnày được viết như thế này, bởi vì kiểu thông thường public static <T> @Nullable java.util.Optional<T> toJavaUtilkhông hợp lệ. Điều này được định nghĩa trong JLS §9.7.4 :
Đó là lỗi thời gian biên dịch nếu chú thích loại T áp dụng cho một loại (hoặc bất kỳ phần nào của loại) trong ngữ cảnh loại và T được áp dụng trong ngữ cảnh loại và chú thích không được chấp nhận.
Ví dụ: giả sử một loại chú thích TA được chú thích bằng meta @Target(ElementType.TYPE_USE). Các điều khoản @TA java.lang.Objectvà java.@TA lang.Objectbất hợp pháp vì tên đơn giản mà @TA gần nhất được phân loại là tên gói. Mặt khác, java.lang.@TA Objectlà hợp pháp.
Khai báo kiểu org.checkerframework.checker.nullness.qual@Nullablelà:
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
Vì vậy, nó đang áp dụng cho quy tắc này.
Cấu trúc này không phá vỡ sự thực thi, vì java.utiltên gói và tên lớp Optionalđược phân tách, có thể được nhìn thấy khi chúng ta xem mã được biên dịch bằng cách sử dụng 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.Optionallà một lớp cục bộ nơi tôi đã sao chép mã Guava, để lấy một ví dụ tối thiểu để khử / biên dịch)
Như bạn có thể thấy, chú thích không còn tồn tại ở đó nữa. Nó chỉ là một điểm đánh dấu cho trình biên dịch để ngăn cảnh báo khi phương thức trả về null (và một gợi ý cho các trình đọc mã nguồn), nhưng nó sẽ không được bao gồm trong mã được biên dịch.
Lỗi trình biên dịch này cũng áp dụng cho các biến như:
private @Nullable2 java.util.Optional<?> o;
Nhưng có thể trở nên chấp nhận được khi chú thích bổ sung thêm loại mục tiêu ElementType.FIELD, như được viết trong cùng một mệnh đề JLS:
Nếu TA được thêm chú thích meta @Target(ElementType.FIELD), thì thuật ngữ @TA java.lang.Objectnày là hợp pháp ở các vị trí có cả bối cảnh khai báo và loại, chẳng hạn như khai báo trường @TA java.lang.Object f;. Ở đây, @TA được coi là áp dụng cho khai báo f (và không áp dụng cho kiểu java.lang.Object) vì TA được áp dụng trong ngữ cảnh khai báo trường.
Nullablehọ đang nói về có vẻ là trongjavax.annotation, khôngjava.util.