Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to pass a Java annotation as a parameter?

Guys is there a way to pass a Annotation as a direct parameter (rather by doing all the reflection overhead)? For example in the following code, I have a annotation Number that holds a int value, I want to pass as a parameter to the addImpl method, how can I do that (other than by reflection)?

Code Snippet:

@Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD}) public @interface Number {     int value(); }  public void add(int x2) {     addImpl(@Number(value = 10) lol, x2); }  public void addImpl(Number a, int b) {     System.out.println(a.value() + b); }  public static void main(String[] args) {     new TestClass().add(3); } 
like image 366
Marcos Roriz Junior Avatar asked Jul 19 '10 15:07

Marcos Roriz Junior


People also ask

Can Java Annotations be inherited?

Annotations, just like methods or fields, can be inherited between class hierarchies. If an annotation declaration is marked with @Inherited , then a class that extends another class with this annotation can inherit it. The annotation can be overridden in case the child class has the annotation.

Can we pass variable in annotation?

It is not possible to give an annotation a changing variable. The value which is passed in to the annotation needs to be known at compile time.

Can Java annotations have methods?

An annotation is a construct associated with Java source code elements such as classes, methods, and variables. Annotations provide information to a program at compile time or at runtime based on which the program can take further action.


2 Answers

Yes, you can pass around annotations like this (just as if they were normal interfaces).

The only thing you can't do is to create instances of that interface at runtime. You can only take existing annotations and pass them around.

import java.lang.annotation.*;  public class Example {      @Retention(RetentionPolicy.RUNTIME)     @Target(ElementType.METHOD)     public static @interface Number {         int value();     }      @Number(value = 42)     public int adder(final int b) throws SecurityException, NoSuchMethodException {         Number number = getClass().getMethod("adder", int.class).getAnnotation(Number.class);         return addImpl(number, b);     }      public int addImpl(final Number a, final int b) {         return a.value() + b;     }      public static void main(final String[] args) throws SecurityException, NoSuchMethodException {         System.out.println(new Example().adder(0));     } } 
like image 64
Joachim Sauer Avatar answered Sep 20 '22 21:09

Joachim Sauer


You can do it like:

public void add(int x2) {     addImpl(new Number() {          @Override         public int value() {             return 10;         }          @Override         public Class<? extends Annotation> annotationType() {             return Number.class;         }     }, x2); } 

Since Number is basically an interface, you have to create an instance of an anonymous class that implements that interface, and pass that to the method.

Although why you want to do this is beyond me. If you need to pass a value to something, you should really use a class.

like image 37
Andrei Fierbinteanu Avatar answered Sep 20 '22 21:09

Andrei Fierbinteanu