Java 一个元素上的多个相同类型的注释?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1554112/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multiple annotations of the same type on one element?
提问by Max A.
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:
编译上述内容时,javac 会抱怨注释重复:
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?
难道根本不可能重复这样的注释吗?迂腐地说,上面@Foo 的两个实例不是因为它们的内容不同而不同吗?
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:
我正在构建一个语法糖化机制来“映射”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; }
}
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.
显然,我希望能够通过 Project 的各种属性快速找到 Employee 的实例。我可以使用不同的 expr() 值两次指定 @Index ,或者采用已接受的答案中指定的方法。即使 Hibernate 这样做并且它不被视为黑客,我认为至少允许在单个元素上具有多个相同类型的注释仍然有意义。
采纳答案by sfussenegger
Two or more annotations of same type aren't allowed. However, you could do something like this:
不允许使用两个或多个相同类型的注释。但是,您可以执行以下操作:
public @interface Foos {
Foo[] value();
}
@Foos({@Foo(bar="one"), @Foo(bar="two")})
public void haha() {}
You'll need dedicated handling of Foos annotation in code though.
不过,您需要专门处理代码中的 Foos 注释。
btw, I've just used this 2 hours ago to work around the same problem :)
顺便说一句,我刚刚在 2 小时前使用它来解决同样的问题:)
回答by KLE
As said by sfussenegger, this isn't possible.
正如 sfussenegger 所说,这是不可能的。
The usual solution is to build an "multiple" annotation, that handles an array of the previous annotation. It is typically named the same, with an 's' suffix.
通常的解决方案是构建一个“多个”注释,它处理前一个注释的数组。它通常命名相同,带有“s”后缀。
By the way, this is very used in big public projects (Hibernate for example), so it shouldn't be considered as a hack, but rather a correct solution for this need.
顺便说一句,这在大型公共项目(例如 Hibernate)中非常有用,因此不应将其视为 hack,而是针对此需求的正确解决方案。
Depending on your needs, it could be better to allow your earlier annotation to handle multiple values.
根据您的需要,最好让您之前的注释处理多个值。
Example:
例子:
public @interface Foo {
String[] bars();
}
回答by mihahh
If you have only 1 parameter "bar" you can name it as "value". In this case you wont have to write the parameter name at all when you use it like this:
如果您只有 1 个参数“bar”,您可以将其命名为“value”。在这种情况下,当您像这样使用它时,您根本不必写参数名称:
@Foos({@Foo("one"), @Foo("two")})
public void haha() {}
a bit shorter and neater, imho..
更短更整洁,恕我直言..
回答by mernst
In Java 8 (released in March 2014), it is possible to write repeated/duplicate annotations. See http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html.
在 Java 8(2014 年 3 月发布)中,可以编写重复/重复的注释。请参阅http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html。
回答by matt1616
combining the other answers into the simplest form ... an annotation with a simple list of values ...
将其他答案组合成最简单的形式......带有简单值列表的注释......
@Foos({"one","two"})
private String awk;
//...
public @interface Foos{
String[] value();
}
回答by Sergei Pikalev
http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
http://docs.oracle.com/javase/tutorial/java/annotations/repeating.html
Starting from Java8 you can describe repeatable annotations:
从 Java8 开始,您可以描述可重复的注释:
@Repeatable(FooValues.class)
public @interface Foo {
String bar();
}
public @interface FooValues {
Foo[] value();
}
Note, value
is required field for values list.
注意,value
是值列表的必填字段。
Now you can use annotations repeating them instead of filling the array:
现在您可以使用注释重复它们而不是填充数组:
@Foo(bar="one")
@Foo(bar="two")
public void haha() {}
回答by Jatin
Apart from the other ways mentioned, there is one more less verbose way in Java8:
除了提到的其他方式之外,Java8 中还有一种更简洁的方式:
@Target(ElementType.TYPE)
@Repeatable(FooContainer.class)
@Retention(RetentionPolicy.RUNTIME)
@interface Foo {
String value();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface FooContainer {
Foo[] value();
}
@Foo("1") @Foo("2") @Foo("3")
class Example{
}
Example by default gets, FooContainer
as an Annotation
示例默认获取,FooContainer
作为注释
Arrays.stream(Example.class.getDeclaredAnnotations()).forEach(System.out::println);
System.out.println(Example.class.getAnnotation(FooContainer.class));
Both the above print:
以上两个打印:
@com.FooContainer(value=[@com.Foo(value=1), @com.Foo(value=2), @com.Foo(value=3)])
@com.FooContainer(value=[@com.Foo(value=1), @com.Foo(value=2), @com.Foo(value=3)])
@com.FooContainer(value=[@com.Foo(value=1), @com.Foo(value=2), @com.Foo(value=3)])
@com.FooContainer(value=[@com.Foo(value=1), @com.Foo(value=2), @com.Foo(value=3)])
回答by Eduardo Alexandre de Souza
In the current version of Java, I was able to resolve this issue with the following annotation:
在当前版本的 Java 中,我能够使用以下注释解决此问题:
@Foo({"one", "two"})