为什么不允许在 FQN 上使用 @NonNull 注解?

Why Are @NonNull Annotation on FQN Not Allowed?

这是 Eclipse 中的一个错误,还是为什么我不能用 @NonNull 注释具有完全限定类型名称 (FQN) 的参数?

    import org.eclipse.jdt.annotation.NonNull;

    public class Foo {
        // No problem
        public void bar(@NonNull String x) {
        }

        // Error: Type annotations are not allowed on type names used to access
        // static members
        public void baz(@NonNull java.lang.String x) {
        }
    }

这不是 Eclipse 中的错误。相反,它与 Java 编译器处理注释类型的方式有关。下面给出的解释说明了这个问题。

首先,@NonNull注解可以应用于类型的任何使用(它被注解为@Target(ElementType.TYPE_USE))。但是,根据 Java 语言规范,它适用的类型是注释 最接近 的类型。这并不总是预期的那样:

在第一种情况下,@NonNull 注释适用于类型 String 的使用,这是一个有效类型。因此,注释有效。

然而,在第二种情况下,注释适用于 java,这是一个包名称。因此,它不是有效的类型,因此注释不能在此处应用。这将导致编译时错误。

Java 语言规范(第 9.7.4 段)指出:

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.

由此我们可以得出结论 @NonNull java.lang.String x 不会起作用,但是 java.lang.@NonNull String x 会的。

另见 The Java Language Specification, Chapter 9.7.4