¿Cuál es el significado de java.util. @ Nullable?




(2)

Al usar anotaciones, esta es la sintaxis que se usa cuando desea escribir un nombre completo para el tipo, en lugar de agregar una declaración de importación.

Citando del manual del marco del verificador :

La sintaxis correcta de Java para escribir una anotación en un nombre de tipo totalmente calificado es colocar la anotación en la parte del nombre simple, como en java.util. @ Nullable List. Pero, por lo general, es mejor agregar import java.util.List a su archivo fuente, para que pueda simplemente escribir @Nullable List.

También se menciona en la página 2 de la especificación JSR308 que se puede descargar here . Dice:

Aparece una anotación de tipo antes del nombre simple del tipo, como en @NonNull String o java.lang. @ NonNull String.

Estoy leyendo el código de Guava donde encontré la anotación [email protected] en algún código. Sé el significado de @Nullable , pero no entiendo este. En particular, no puedo encontrar una clase llamada Nullable en el paquete java.util . Por favor, que alguien me diga cuál es el significado de este [email protected] :

public static <T> java.util.@Nullable Optional<T> toJavaUtil(
    @Nullable Optional<T> googleOptional) {
  return googleOptional == null ? null : googleOptional.toJavaUtil();
}

La línea public static <T> [email protected] Optional<T> toJavaUtil se escribe así, porque el estilo habitual public static <T> @Nullable java.util.Optional<T> toJavaUtil no 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 @Target(ElementType.TYPE_USE) con solo @Target(ElementType.TYPE_USE) . Los términos @TA java.lang.Object y [email protected] lang.Object son ilegales porque el nombre simple al que @TA está más cerca se clasifica como un nombre de paquete. Por otro lado, [email protected] Object es legal.

La declaración de tipo de [email protected] es:

@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})

Entonces se aplica a esta regla.

Que esta estructura no interrumpa la ejecución, ya que el paquete java.util y el nombre de clase Optional se 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.Optional es 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 volverse aceptable cuando la anotación adicionalmente obtiene el tipo de destino ElementType.FIELD , como está escrito en la misma cláusula JLS:

Si TA se @Target(ElementType.FIELD) adicionalmente con @Target(ElementType.FIELD) , entonces el término @TA java.lang.Object es legal en ubicaciones que son contextos de declaración y 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.





java