La línea public static <T> java.util.@Nullable Optional<T> toJavaUtilse escribe así, porque el estilo habitual public static <T> @Nullable java.util.Optional<T> toJavaUtilno es válido. Esto se define en el JLS §9.7.4 :
Es un error en tiempo de compilación si una anotación de tipo T se aplica a un tipo (o cualquier parte de un tipo) en un contexto de tipo, y T es aplicable en contextos de tipo, y la anotación no es admisible.
Por ejemplo, suponga un tipo de anotación TA que se metaanota con just @Target(ElementType.TYPE_USE). Los términos @TA java.lang.Objecty java.@TA lang.Objectson ilegales porque el nombre simple al que @TA es más cercano se clasifica como un nombre de paquete. Por otro lado, java.lang.@TA Objectes legal.
La declaración de tipo de org.checkerframework.checker.nullness.qual@Nullablees:
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
Entonces se aplica a esta regla.
Se puede ver que esta estructura no interrumpe la ejecución, ya que el java.utilnombre del paquete y la clase Optionalse dividieron, se puede ver cuando miramos el código compilado usando 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.Optionales una clase local donde copié el código de Guava para obtener un ejemplo mínimo para descompilar / compilar)
Como puede ver, la anotación ya no existe. Es solo un marcador para el compilador para evitar una advertencia cuando el método devuelve nulo (y una pista para los lectores de código fuente), pero no se incluirá en el código compilado.
Este error del compilador también se aplica a variables como:
private @Nullable2 java.util.Optional<?> o;
Pero puede ser aceptable cuando la anotación adicionalmente obtiene el tipo de destino ElementType.FIELD, como está escrito en la misma cláusula JLS:
Si TA está adicionalmente meta-anotado con @Target(ElementType.FIELD), entonces el término @TA java.lang.Objectes legal en ubicaciones que son tanto contextos de declaración como de tipo, como una declaración de campo @TA java.lang.Object f;. Aquí, se considera que @TA se aplica a la declaración de f (y no al tipo java.lang.Object) porque TA es aplicable en el contexto de declaración de campo.
Nullableque está hablando no parece estar enjavax.annotation, nojava.util.