Java注释成员可以使用哪些类型?


238

今天,我想按照本文档创建我的第一个注释界面,但出现此编译器错误

Invalid type for annotation member":
public @interface MyAnnotation {
    Object myParameter;
    ^^^^^^
}

显然Object不能用作注释成员的类型。不幸的是,我找不到有关可以普遍使用的类型的任何信息。

我通过反复试验发现了这一点:

  • String →有效
  • int →有效
  • Integer →无效(令人惊讶地)
  • String[] →有效(令人惊讶)
  • Object →无效

也许有人可以阐明实际允许的类型以及原因。


可能因注释而异-请显示您要编写的代码。
djna

2
添加到问题。但我认为这不会改变。
Daniel Rikowski 09年

Answers:


324

它由JLS的9.6.1节指定。注释成员类型必须是以下之一:

  • 原始
  • 枚举
  • 另一个注释
  • 以上任何一个的数组

它似乎确实有限制性,但无疑有其原因。

另请注意,String[][]上述规则暗中禁止使用多维数组(例如)。

本答案所述,不允许使用Class数组。


33
如何找到这些页面/文档?我发誓我会先在Google上搜索,然后再问StackOverlow和许多Java问题,有人会发布一个指向JSL的链接来回答我的问题。为什么我无法通过Google找到这些页面?
Daniel Rikowski 09年

10
JLS对Google不太友好。您只需要知道它在那里。
skaffman

1
在sun的站点上的注释指南中也有相同的信息(发现谷歌搜索):java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
wds

1
是的,我也找到了该页面,但我一定错过了该句子,它隐藏在所有散文中。我一直在寻找其他类似表格或列表的内容。
Daniel Rikowski 09年

13
上面的列表中缺少的是“注释”。您可以具有包含另一个注释或另一个注释的数组的注释。
马特

58

我同意Skaffman提供的可用类型。

附加限制:它必须是一个编译时常量

例如,禁止以下行为:

@MyAnnot("a" + myConstantStringMethod())
@MyAnnot(1 + myConstantIntMethod())

31

也不要忘记,注释本身可以成为注释定义的一部分。这允许一些简单的注释嵌套-在您希望多次显示一个注释的情况下非常方便。

例如:

@ComplexAnnotation({
    @SimpleAnnotation(a="...", b=3),
    @SimpleAnnotation(a="...", b=3),
    @SimpleAnnotation(a="...", b=3)
})
public Object foo() {...}

这里SimpleAnnotation

@Target(ElementType.METHOD)
public @interface SimpleAnnotation {
    public String a();
    public int b();
)

并且ComplexAnnotation

@Target(ElementType.METHOD)
public @interface ComplexAnnotation {
    public SimpleAnnotation[] value() default {};
)

示例取自:http : //web.archive.org/web/20131216093805/https : //blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

(原始URL:https : //blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations


6
使用Java 8 @Repeatable不再需要此功能。
Mordechai

11

注释的概念非常适合我的项目设计,直到我意识到注释中不能包含复杂的数据类型。我通过使用要实例化的类而不是该类的实例化对象来解决该问题。它不是完美的,但Java很少。

@interface Decorated { Class<? extends PropertyDecorator> decorator() }

interface PropertyDecorator { String decorate(String value) }

class TitleCaseDecorator implements PropertyDecorator {
    String decorate(String value)
}

class Person {
    @Decorated(decorator = TitleCaseDecorator.class)
    String name
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.