java循环注释

java循环注释,java,annotations,Java,Annotations,我想创建带有注释的树结构 @Retention(RetentionPolicy.RUNTIME) public @interface MyNode { String name(); MyNode next() default null; } 但编译器告诉我们它是循环的,所以它是不允许的 我想知道为什么这是不允许的,我怎么能做这样的东西 注释是编译时常量 注释成员只能是编译时常量(字符串、原语、枚举、注释、类文本) 任何引用自身的东西都不能是常量,因此注释不能引用自身 有趣的

我想创建带有注释的树结构

@Retention(RetentionPolicy.RUNTIME)
public @interface MyNode {
     String name();
     MyNode next() default null;
}
但编译器告诉我们它是循环的,所以它是不允许的

我想知道为什么这是不允许的,我怎么能做这样的东西

  • 注释是编译时常量
  • 注释成员只能是编译时常量(字符串、原语、枚举、注释、类文本)
  • 任何引用自身的东西都不能是常量,因此注释不能引用自身
  • 有趣的是:Java语言规范中有一部分似乎与此相矛盾:

    注释类型声明上的注释称为 元注释。注释类型可用于注释其自己的类型 宣言。更一般地说,传递闭包中的循环 允许使用“注释”关系。比如说,这是合法的 用另一种注释类型注释注释类型声明, 并用前一个类型注释后一个类型的声明。 (预定义的元注释类型包含几个这样的类型 循环。)
    []

    但这两种方法都有编译错误(注释引用本身):

    这(两个注释相互引用):


    如果您真的需要它,您可能希望使用Sun Java 5编译器,在这里不强制执行此限制


    但也许更好的解决方案是将节点存储在一个数组中,让每个节点都有其子节点的索引。

    它不是树结构,只是线性列表。尝试使用数组来简化声明

    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyNode {
         String name();
    }
    
    和包装:

    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyNodes {
         MyNode[] value();
    }
    
    现在,只需声明为数组:

    @MyNodes({ 
        @MyNode(name = "name1"),
        @MyNode(name = "name2")
    })
    public class MyClass {
    }
    

    您只是在尝试注释,还是有什么特别的问题?@beny23,我需要指定路径,比如非常简化的XPath或文件系统上的目录路径
    /path/to/an/element
    ,我不太明白您为什么要创建注释链接列表?带路径的字符串值不足以满足您的需要吗?我不想使用字符串,因为提取路径元素时会有很多混乱。我可以简单地使用字符串数组,但如果我需要将此链表扩展到一个包含更多子级的树(例如,两个left()和right())的树,那该怎么办呢?嘿,似乎是不可能的:(.我说得对吗?注释本身不保存在.class文件中(如string或int),而是在运行时创建的?@misha注释声明本身驻留在.class文件中(注释是一个接口)。注释是否出现在注释类中取决于“@Retention”,我认为规范的一部分引用了这样的代码,它编译时没有错误:
    @NewAnnotationType public@interface NewAnnotationType{}
    @Jörn你当然是对的。我想,这就是注释处理器以循环方式工作的原因:-)@sean patrick floyd,
    任何引用自身的对象都不能是常数,因此注释不能引用自身
    。您能更详细地解释一下吗。有两个不同的对象,但类型相同。其中一个对象与另一个对象有链接。将它们放在一起有什么问题。当有两个不同类型的对象时nt类型一切工作都很完美:
    @interface Annotation1{Annotation2 annot();}
    您可能想使用Sun Java 5编译器,请不要使用。JDK 7在这里,现在不是跳回1.5的时候,因此我建议了一个更好的解决方案。
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyNodes {
         MyNode[] value();
    }
    
    @MyNodes({ 
        @MyNode(name = "name1"),
        @MyNode(name = "name2")
    })
    public class MyClass {
    }