Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiple annotations of the same type on one element?

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.

like image 452
Max A. Avatar asked Oct 12 '09 11:10

Max A.


People also ask

Can we apply two annotations together?

It is also possible to use multiple annotations on the same declaration: @Author(name = "Jane Doe") @EBook class MyClass { ... } If the annotations have the same type, then this is called a repeating annotation: @Author(name = "Jane Doe") @Author(name = "John Smith") class MyClass { ... }

What is repeatable annotation type?

The value of the @Repeatable meta-annotation, in parentheses, is the type of the container annotation that the Java compiler generates to store repeating annotations. In this example, the containing annotation type is Schedules , so repeating @Schedule annotations is stored in an @Schedules annotation.

How many annotations can be applied on any method?

There are three types of annotations.

What is @target annotation in Java?

If an @Target meta-annotation is present, the compiler will enforce the usage restrictions indicated by ElementType enum constants, in line with JLS 9.7. 4. For example, this @Target meta-annotation indicates that the declared type is itself a meta-annotation type.


2 Answers

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.

like image 95
sfussenegger Avatar answered Oct 21 '22 20:10

sfussenegger


Repeating annotations in Java 8

In Java 8 (released in March 2014), it is possible to write repeated/duplicate annotations.

See tutorial, Repeating Annotations.

See specification, JEP 120: Repeating Annotations.

like image 29
mernst Avatar answered Oct 21 '22 18:10

mernst