Java - 如何创建仅适用于类型上下文的注解类型? (PURE 类型注解)

Java - How do I create an annotation type that is only applicable in type contexts? (PURE type annotation)

要创建适用于类型上下文的类型注释,除了使用 @Target(ElementType.TYPE_USE) 对注释类型进行元注释外别无他法。但是,由于 Java 设计者的错误决定,此注释也适用于声明上下文。

根据 Java SE 文档,它是这样写的:

The constant TYPE_USE corresponds to the type contexts in JLS 4.11, as well as to two declaration contexts: type declarations (including annotation type declarations) and type parameter declarations.

For example, an annotation whose type is meta-annotated with @Target(ElementType.TYPE_USE) may be written on the type of a field (or within the type of the field, if it is a nested, parameterized, or array type), and may also appear as a modifier for, say, a class declaration.

The TYPE_USE constant includes type declarations and type parameter declarations as a convenience for designers of type checkers which give semantics to annotation types. For example, if the annotation type NonNull is meta-annotated with @Target(ElementType.TYPE_USE), then @NonNull class C {...} could be treated by a type checker as indicating that all variables of class C are non-null, while still allowing variables of other classes to be non-null or not non-null based on whether @NonNull appears at the variable's declaration.

尽管如此,我相信 TYPE_USE 最初打算用于 JLS 4.11 中描述的 16 种类型上下文。但是 Java 设计者决定将其用途扩展到声明上下文。

不知:

关于你的第一个问题,@Sweeper 给出了原因。通常,写在类型声明上的类型注释被视为适用于该类型的每次使用。这是一个很常见的习惯用法,要求每个注释设计者都扩展 @Target 注释会很麻烦。此外,写@Target({TYPE_USE, TYPE})误导,因为它声明的注解既是类型注解又是声明注解,这不是设计者的目标,与设计师的目标。

这是 Java 设计的另一个优势。在字段或方法声明中,Java 将声明上的声明注释与字段类型或方法 return 类型上的类型注释区分开来。在 class 声明上编写 TYPE_USE 注释的能力提供了一种类似的方式来区分在 class 声明上编写的注释的意图和目的。

关于你的第二个问题,你可以编写一个注解处理器,当注解写在你希望禁止的位置时,它会发出错误。您已经在使用注释处理器来强制执行类型注释的语义,因此您只需要对其进行调整。