在一个元素上有多个相同类型的注释?在 Java 8 中重复注释

2022-08-31 10:35:58

我试图在单个元素(在本例中为方法)上打两个或多个相同类型的注释。以下是我正在使用的近似代码:

public class Dupe {
    public @interface Foo {
      String bar();
    }

    @Foo(bar="one")
    @Foo(bar="two")
    public void haha() {}
}

在编译上述内容时,javac 会抱怨重复的注释:

max@upsight:~/work/daybreak$ javac Dupe.java 
Dupe.java:5: duplicate annotation

难道根本不可能重复这样的注释吗?从学理上讲,上述两个@Foo实例不是因为它们的内容不同而不同吗?

如果上述方法无法实现,有哪些可能的解决方法?

更新:我被要求描述我的用例。来了。

我正在构建一个语法糖机制,将POJO“映射”到MongoDB等文档存储中。我想允许将索引指定为 getter 或 setter 上的注释。下面是一个人为的示例:

public class Employee {
    private List<Project> projects;

    @Index(expr = "project.client_id")
    @Index(expr = "project.start_date")
    public List<Project> getProjects() { return projects; }
}

显然,我希望能够通过 Project 的各种属性快速找到 Employee 的实例。我可以使用不同的 expr() 值指定两次@Index,也可以采用在接受的答案中指定的方法。尽管Hibernate这样做并且不被认为是一个黑客,但我认为至少允许在单个元素上具有相同类型的多个注释仍然是有意义的。


答案 1

注意:由于Java 8引入了@Repeatable注释,因此此答案已部分过时(请参阅@mernst的答案)。不过,对@Foos容器注释和专用处理的需求仍然存在。

不允许使用两个或多个相同类型的批注。但是,您可以执行如下操作:

public @interface Foos {
    Foo[] value();
}

// pre Java 8
@Foos({@Foo(bar="one"), @Foo(bar="two")})
public void haha() {}

// post Java 8 with @Repeatable(Foos.class) on @Foo
@Foo(bar="one") @Foo(bar="two")
public void haha() {}

不过,您需要专门处理代码中的注释。Foos


答案 2

在 Java 8 中重复注释

Java 8(2014年3月发布)中,可以编写重复/重复的注释。

请参阅教程重复批注

请参阅规范 JEP 120:重复注释


推荐