Рядок public static <T> java.util.@Nullable Optional<T> toJavaUtilнаписаний так, оскільки звичайний стиль public static <T> @Nullable java.util.Optional<T> toJavaUtilнедійсний. Це визначено у § 9.7.4 JLS :
Це помилка часу компіляції, якщо анотація типу 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), оскільки ТА застосовується в контексті декларації на місцях.
NullableВони говорять про те , як представляється, вjavax.annotationНЕjava.util.