【问题标题】:Which types can be used for Java annotation members?Java注解成员可以使用哪些类型?
【发布时间】:2010-11-30 07:42:16
【问题描述】:

今天我想在this documentation 之后创建我的第一个注释接口,但我得到了这个编译器错误

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

显然Object 不能用作注解成员的类型。不幸的是,我找不到任何关于一般可以使用哪些类型的信息。

这是我通过反复试验发现的:

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

也许有人可以阐明哪些类型实际上是允许的以及为什么。

【问题讨论】:

  • 可能因注释而异 - 请显示您尝试编写的代码。
  • 已添加到问题中。但我不认为它会有所不同。

标签: java annotations


【解决方案1】:

section 9.6.1 of the JLS 指定。注释成员类型必须是以下之一:

  • 原始
  • 字符串
  • 一个枚举
  • 另一个注解
  • 上述任何一项的数组

它看起来确实有限制,但毫无疑问是有原因的。

还要注意多维数组(例如String[][])被上述规则隐式禁止。

this answer 中所述,不允许使用 Class 数组。

【讨论】:

  • 如何找到那些页面/文档?我发誓我每次在 StackOverlow 和许多 Java 问题上提问之前都会谷歌,有人发布了一个指向 JSL 的链接,它回答了我的问题。为什么我没有通过 Google 找到这些页面?!
  • JLS 对 Google 不太友好。你只需要知道它就在那里。
  • sun 网站上的注释指南中也提供了相同的信息(确实找到了谷歌搜索):java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
  • 是的,我也找到了那个页面,但我一定错过了隐藏在所有散文文本中的那句话。我一直在寻找更像表格或列表的东西。
  • 上面列表中缺少的是“注释”。您可以拥有一个包含另一个注释或另一个注释数组的注释。
【解决方案2】:

我同意 Skaffman 的可用类型。

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

例如,以下是禁止的:

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

【讨论】:

    【解决方案3】:

    别忘了注解本身也可以是注解定义的一部分。这允许一些简单的注释嵌套 - 在您希望一个注释出现多次的情况下很方便。

    例如:

    @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

    (原网址:https://blogs.oracle.com/toddfast/entry/creating_nested_complex_java_annotations

    【讨论】:

    • 使用 Java 8 @Repeatable,不再需要了。
    【解决方案4】:

    注解的概念非常适合我的项目设计,直到我意识到注解中不能包含复杂的数据类型。我通过使用我想要实例化的类而不是该类的实例化对象来解决它。它并不完美,但 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
    }
    

    【讨论】:

    • 你在@interface Decorated 上使用了什么目标类型?试图在我的项目中使用这种模式,一切都编译但在运行时我在“字符串名称”上得到一个大的胖空指针(在我的例子中: List myList (试图用它需要的东西列表来装饰一个通用处理器处理某事)
    【解决方案5】:

    根据 Oracle,注释元素的有效类型是:

    1. Primitives (byte, char, int, long float, double)
    2. Enums
    3. Class (Think generics here Class <?>, Class<? extends/super T>>)
    4. String
    5. Array of the above (array[] of primitives, enums, String, or Class)
    5. Another annotation.
    

    需要注意的是,所有元素本质上都被认为是公共的和抽象的。

    因此

     static final variable(s) allowed as well.
    

    【讨论】:

      猜你喜欢
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-29
      • 2011-02-16
      • 2016-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多