一个元素上有多个相同类型的注释?

2022-01-13 00:00:00 annotations java

我试图在单个元素上添加两个或多个相同类型的注释,在本例中是一个方法.这是我正在使用的大致代码:

public class Dupe {公共@interface Foo {字符串条();}@Foo(bar="one")@Foo(bar="两个")公共无效哈哈(){}}

编译上面的时候,javac报错注解:

<上一页>max@upsight:~/work/daybreak$ javac Dupe.javaDupe.java:5:重复注释

难道就不能像这样重复注释吗?学究起来,上面的两个@Foo 实例不是因为内容不同而不同吗?

如果上述方法不可行,有哪些潜在的解决方法?

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

我正在构建一种语法糖化机制,将 POJO映射"到 MongoDB 等文档存储.我想允许将索引指定为 getter 或 setter 上的注释.这是一个人为的例子:

公共类员工{私人名单<项目>项目;@Index(expr = "project.client_id")@Index(expr = "project.start_date")公开列表<项目>getProjects() { 返回项目;}}

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

解决方案

注意:由于 Java 8 引入了 @Repeatable 批注(请参阅 @mernst 的回答),此答案已部分过时.但是仍然需要 @Foos 容器注释和专用处理.

不允许使用两个或多个相同类型的注释.但是,您可以这样做:

public @interface Foos {Foo[] 值();}//Java 8 之前@Foos({@Foo(bar=一个"), @Foo(bar=两个")})公共无效哈哈(){}//在@Foo 上发布带有@Repeatable(Foos.class) 的Java 8@Foo(bar=一个") @Foo(bar=两个")公共无效哈哈(){}

您需要专门处理代码中的 Foos 注释.

I'm attempting to slap two or more annotations of the same type on a single element, in this case, a method. Here's the approximate code that I'm working with:

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

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

When compiling the above, javac complains about a duplicate annotation:

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

Is it simply not possible to repeat annotations like this? Pedantically speaking, aren't the two instances of @Foo above different due to their contents being different?

If the above isn't possible, what are some potential workarounds?

UPDATE: I've been asked to describe my use case. Here goes.

I'm building a syntax sugarish mechanism to "map" POJOs to document stores such as MongoDB. I want to allow indexes to be specified as annotations on the getters or setters. Here's a contrived example:

public class Employee {
    private List<Project> projects;

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

Obviously, I want to be able to quickly find instances of Employee by various properties of Project. I can either specify @Index twice with different expr() values, or take the approach specified in the accepted answer. Even though Hibernate does this and it's not considered a hack, I think it still makes sense to at least allow having multiple annotations of the same type on a single element.

解决方案

Note: This answer is partially outdated since Java 8 introduced the @Repeatable annotation (see answer by @mernst). The need for a @Foos container annotation and dedicated handling still remain though.

Two or more annotations of same type aren't allowed. However, you could do something like this:

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() {}

You'll need dedicated handling of Foos annotation in code though.

相关文章