带有类型参数的注释属性

定义Java接口时,可以使用类型参数声明方法,例如:

public interface ExampleInterface { <E extends Enum> Class options(); } 

同样的事情在注释中不起作用。 例如,这是非法的:

 public @interface ExampleAnnotation { <E extends Enum> Class options(); } 

我可以通过使用原始类型Enum来获得我想要的东西:

 public @interface ExampleAnnotation { @SuppressWarnings("rawtypes") Class options(); } 

究竟是什么原因导致无法使用类型参数声明注释属性?

我认为这是可能的,但它需要对语言规范进行大量补充,这是不合理的。

首先,对于你的枚举示例,你可以使用Class> options Class> options

Class options还有另一个问题Class options Class options :因为Enum.class是一个Class ,它是一个Class Class ,它对options=Enum.class是合法的

Class> options不会发生这种情况Class> options Class> options ,因为Enum不是Enum的子类型,在杂乱的原始类型处理中是一个相当偶然的事实。

回到一般问题。 由于有限的属性类型中, Class是唯一具有类型参数的类型,并且通配符通常足够表达,因此您的关注点不值得解决。

让我们进一步概括问题,假设有更多的属性类型,并且在许多情况下通配符不够强大。 例如,假设允许Map ,例如

 Map options(); options={"a":1, "b":2} // suppose we have "map literal" 

假设我们想要一个attrbite类型为任何类型x Map 。 这不能用通配符表示 – Map意味着对任何x,y Map

一种方法是允许类型的类型参数: Map 。 这实际上非常有用。 但这是打字系统的一个重大变化。

另一种方法是重新解释注释类型中方法的类型参数。

  Map options(); options={ "a":"a", "b":"b" } // infer X=String 

在当前对方法类型参数,推理规则,inheritance规则等的理解中,这根本不起作用。我们需要更改/添加很多东西才能使它工作。

在任何一种方法中,如何将X传递给注释处理器都是一个问题。 我们必须发明一些额外的机制来携带实例的类型参数。

The Java™语言规范第三版说:

通过其上下文无关语法对注释类型声明施加以下限制:

  • 注释类型声明不能是通用的。
  • 不允许使用扩展条款。 (注释类型隐式扩展annotation.Annotation。)
  • 方法不能有任何参数
  • 方法不能有任何类型参数
  • 方法声明不能有throws子句

Java语言规范的第9.6节描述了注释。 其中一句话是:

如果在注释类型中声明的方法的返回类型是除以下之一之外的任何类型,则是编译时错误:其中一种基本类型,String,Class和任何类的调用,一个枚举类型(§8.9) ),注释类型或前述类型之一的数组(第10节)。 如果在注释类型中声明的任何方法具有覆盖等同于在类Object或接口annotation.Annotation中声明的任何公共或受保护方法的签名,则它也是编译时错误。

然后它说以下,这是我认为这个问题的关键:

请注意,这与generics方法的禁止不冲突,因为通配符消除了对显式类型参数的需要。

所以它建议我应该使用通配符,并且不需要类型参数。 为了摆脱原始类型Enum ,我只需要在他的回答中使用Enum作为无可争议的建议:

 public @interface ExampleAnnotation { Class> options(); } 

可能允许类型参数会打开一堆蠕虫,因此语言设计者决定简单地禁止它们,因为你可以通过通配符得到你需要的东西。

他们想要引入注释,以便人们只能将它们用作,,,注释。 并防止开发人员将逻辑放入其中。 即使用注释开始编程 ,这可能会使我认为Java看起来像一个非常不同的语言。 因此,Java语言规范中的上下文无关语法说明。

通过其上下文无关语法对注释类型声明施加以下限制:

 Annotation type declarations cannot be generic. No extends clause is permitted. (Annotation types implicitly extend annotation.Annotation.) Methods cannot have any parameters Methods cannot have any type parameters 

(http://java.sun.com/docs/books/jls/third_edition/html/interfaces.html)

为了更好地理解我的意思,看看这个JVM黑客的作用: http : //www.cs.rice.edu/~mgricken/research/xajavac/

他创建And,或注释作为指令并使用它们处理其他注释。 无价!