Java-如何创建仅适用于类型上下文的注释类型? (PURE类型注释) [英] Java - How do I create an annotation type that is only applicable in type contexts? (PURE type annotation)

查看:190
本文介绍了Java-如何创建仅适用于类型上下文的注释类型? (PURE类型注释)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

根据Java SE文档,其内容为:

常量TYPE_USE对应于JLS 4.11中的类型上下文,以及两个声明上下文:类型声明(包括注释类型声明)和类型参数声明.

例如,其类型用@Target(ElementType.TYPE_USE)进行元注释的注释可以写在字段的类型上(如果是嵌套,参数化或数组类型,则可以写在字段的类型内),并且可能还会作为类声明的修饰符出现.

TYPE_USE常量包括类型声明和类型参数声明,以方便类型检查器的设计者使用,这些检查器为注释类型提供了语义.例如,如果注释类型NonNull用@Target(ElementType.TYPE_USE)进行元注释,则类型检查器可以将@NonNull class C {...}视为指示类C的所有变量都不为空,同时仍允许其他类的变量根据@NonNull是否出现在变量的声明中而为非空或非空.

尽管如此,我相信TYPE_USE原本打算用于

  • 如何创建仅适用于类型上下文的注释类型? (又称纯类型注释)
  • 解决方案

    关于您的第一个问题,@ Sweeper给出了原因.按照惯例,写在类型声明上的类型注释被视为适用于该类型的每次使用.这是一个非常常见的习惯用法,要求每个注释设计者扩展@Target注释会很麻烦.此外,编写@Target({TYPE_USE, TYPE})可能会误导,因为它声明的注释既是类型注释又是声明注释,这不是设计者的目标,并且与设计者的目标含义不同./p>

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

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

    To create a type annotation that is applicable in type contexts, there is no way other than meta-annotating the annotation type with @Target(ElementType.TYPE_USE). However, this annotation also becomes applicable in declaration contexts due to the bad decision of the Java designers.

    According to the Java SE documentation, it reads:

    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.

    Nonetheless, I believe TYPE_USE was originally intended to be used in 16 type contexts as described in JLS 4.11. But the Java designers made a decision to extend its usage to declaration contexts.

    I wonder:

    • WHY on earth did they make this decision when you can expand an annotation's applicability simply by adding more elements to the @Target annotation. Any specific reason other than "convenience"?
    • HOW can I create an annotation type that is ONLY applicable in type contexts? (aka. Pure type annotation)

    解决方案

    Regarding your first question, @Sweeper gave the reason. Conventionally a type annotation written on a type declaration is treated as applying to every use of the type. This is such a common idiom that it would be troublesome to require every annotation designer to expand the @Target annotation. Furthermore, writing @Target({TYPE_USE, TYPE}) would be misleading, because it declares an annotation that is both a type annotation and a declaration annotation, which is not the designer's goal and has a different meaning than the designer's goal.

    Here is another advantage to the Java design. In a field or method declaration, Java distinguishes declaration annotations on the declaration from type annotations on the field type or method return type. The ability to write a TYPE_USE annotation on a class declaration gives a similar way to distinguish the intent and purpose of annotations written on class declarations.

    Regarding your second question, you can write an annotation processor that issues an error when an annotation in written at a location that you wish to prohibit. You are already using an annotation processor to enforce the semantics of type annotations, so you just need to tweak it.

    这篇关于Java-如何创建仅适用于类型上下文的注释类型? (PURE类型注释)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆