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

6

为什么我不能在Eclipse中使用完全限定类型名(FQN)来注释参数,如@NonNull?这是Eclipse的一个bug吗?

    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) {
        }
    }
1个回答

9
这不是Eclipse的错误,而是与Java编译器处理注解类型的方式有关。下面的解释说明了这个问题。
首先,@NonNull注解可以应用于任何类型的使用(它用@Target(ElementType.TYPE_USE)进行注释)。然而,根据Java语言规范,它适用的类型是最接近注解的类型。这并不总是符合预期的:
在第一个案例中,@NonNull注解适用于类型String的使用,这是一个有效的类型。因此,注解是有效的。
然而,在第二种情况中,注解适用于java,这是一个包名称。因此,它不是一个有效的类型,所以注解不能应用于此处。这将导致编译时错误。
Java语言规范(第9.7.4段)规定:
例如,假设一个注解类型TA,该类型仅用@Target(ElementType.TYPE_USE)进行元注释。术语@TA java.lang.Objectjava.@TA lang.Object是非法的,因为与@TA最接近的简单名称被归类为包名称。另一方面,java.lang.@TA Object是合法的。
由此我们可以得出结论:@NonNull java.lang.String x将不起作用,但java.lang.@NonNull String x将起作用。
另请参见Java语言规范第9.7.4章

3
谢谢您提供这么好的解释!我认为这个设计不太好。java.lang.@NonNull String 看起来很丑,但是没关系,它能用 :) - Vertex
我从来没有想到你可以像这样注释:java.lang.@NonNull String - Next Developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接