Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to read the value of a annotation in java?

People also ask

How do you find the parameters of annotations?

getAnnotation(Annotation. class). param1() to get the param1 value. Here you have named your annotation interface as Annotation.

Is annotation inherited in Java?

Because there is no multiple inheritance in Java, annotations on interfaces cannot be inherited. Even when the annotation is inherited, the application code that retrieves the annotation of a certain element can distinguish between the annotations that are inherited and those that are declared on the entity itself.

Do Java annotations do anything?

Java annotations are used to provide meta data for your Java code. Being meta data, Java annotations do not directly affect the execution of your code, although some types of annotations can actually be used for that purpose.


Yes, if your Column annotation has the runtime retention

@Retention(RetentionPolicy.RUNTIME)
@interface Column {
    ....
}

you can do something like this

for (Field f: MyClass.class.getFields()) {
   Column column = f.getAnnotation(Column.class);
   if (column != null)
       System.out.println(column.columnName());
}

UPDATE : To get private fields use

Myclass.class.getDeclaredFields()

Of course it is. Here is a sample annotation:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

    String testText();
}

And a sample annotated method:

class TestClass {

    @TestAnnotation(testText="zyx")
    public void doSomething() {}
}

And a sample method in another class that prints the value of the testText:

Method[] methods = TestClass.class.getMethods();
for (Method m : methods) {
    if (m.isAnnotationPresent(TestAnnotation.class)) {
        TestAnnotation ta = m.getAnnotation(TestAnnotation.class);
        System.out.println(ta.testText());
    }
}

Not much different for field annotations like yours.

Cheerz!


I've never done it, but it looks like Reflection provides this. Field is an AnnotatedElement and so it has getAnnotation. This page has an example (copied below); quite straightforward if you know the class of the annotation and if the annotation policy retains the annotation at runtime. Naturally if the retention policy doesn't keep the annotation at runtime, you won't be able to query it at runtime.

An answer that's since been deleted (?) provided a useful link to an annotations tutorial that you may find helpful; I've copied the link here so people can use it.

Example from this page:

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno {
  String str();

  int val();
}

class Meta {
  @MyAnno(str = "Two Parameters", val = 19)
  public static void myMeth(String str, int i) {
    Meta ob = new Meta();

    try {
      Class c = ob.getClass();

      Method m = c.getMethod("myMeth", String.class, int.class);

      MyAnno anno = m.getAnnotation(MyAnno.class);

      System.out.println(anno.str() + " " + anno.val());
    } catch (NoSuchMethodException exc) {
      System.out.println("Method Not Found.");
    }
  }

  public static void main(String args[]) {
    myMeth("test", 10);
  }
}

Elaborating to the answer of @Cephalopod, if you wanted all column names in a list you could use this oneliner:

List<String> columns = 
        Arrays.asList(MyClass.class.getFields())
              .stream()
              .filter(f -> f.getAnnotation(Column.class)!=null)
              .map(f -> f.getAnnotation(Column.class).columnName())
              .collect(Collectors.toList());

While all the answers given so far are perfectly valid, one should also keep in mind the google reflections library for a more generic and easy approach to annotation scanning, e.g.

 Reflections reflections = new Reflections("my.project.prefix");

 Set<Field> ids = reflections.getFieldsAnnotatedWith(javax.persistence.Id.class);

In common case you have private access for fields, so you CAN'T use getFields in reflection. Instead of this you should use getDeclaredFields

So, firstly, you should be aware if your Column annotation has the runtime retention:

@Retention(RetentionPolicy.RUNTIME)
@interface Column {
}

After that you can do something like this:

for (Field f: MyClass.class.getDeclaredFields()) {
   Column column = f.getAnnotation(Column.class);
       // ...
}

Obviously, you would like to do something with field - set new value using annotation value:

Column annotation = f.getAnnotation(Column.class);
if (annotation != null) {
    new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
        object,
        myCoolProcessing(
            annotation.value()
        )
    );
}

So, full code can be looked like this:

for (Field f : MyClass.class.getDeclaredFields()) {
    Column annotation = f.getAnnotation(Column.class);
    if (annotation != null)
        new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
                object,
                myCoolProcessing(
                        annotation.value()
                )
        );
}