What's the meaning of java.util.@Nullable?

SetDaemon :

I'm reading the code of Guava where I found the annotation java.util.@Nullable in some code. I know the meaning of @Nullable, but I don't understand this one. In particular, I can't find a class called Nullable in the package java.util. Please, someone tell me what's the meaning of this java.util.@Nullable:

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

The line public static <T> java.util.@Nullable Optional<T> toJavaUtil is written like this, because the usual style public static <T> @Nullable java.util.Optional<T> toJavaUtil is invalid. This is defined in the JLS §9.7.4:

It is a compile-time error if an annotation of type T applies to a type (or any part of a type) in a type context, and T is applicable in type contexts, and the annotation is not admissible.

For example, assume an annotation type TA which is meta-annotated with just @Target(ElementType.TYPE_USE). The terms @TA java.lang.Object and java.@TA lang.Object are illegal because the simple name to which @TA is closest is classified as a package name. On the other hand, java.lang.@TA Object is legal.

The type declaration of org.checkerframework.checker.nullness.qual@Nullable is:

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

So it is applying to this rule.

That this structure doesn't break the execution, since package java.util and class name Optional were split, can be seen when we look at the compiled code using 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 is a local class where I copied the Guava code in, in order to get a minimal example to de-/compile)

As you can see, the annotation doesn't exist there anymore. It is only a marker for the compiler to prevent a warning when the method returns null (and a hint for the source code readers), but it won't be included in the compiled code.


This compiler error also applies to variables like:

private @Nullable2 java.util.Optional<?> o;

But can become acceptable when the annotation additionally gets the target type ElementType.FIELD, as written in the same JLS clause:

If TA is additionally meta-annotated with @Target(ElementType.FIELD), then the term @TA java.lang.Object is legal in locations which are both declaration and type contexts, such as a field declaration @TA java.lang.Object f;. Here, @TA is deemed to apply to the declaration of f (and not to the type java.lang.Object) because TA is applicable in the field declaration context.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=304281&siteId=1