'Run code on all Java annotations during runtime

I would like to execute code during runtime on all annotated fields, including fields in sub-classes. As a minimal example:

class X {
    // A custom annotation on `x`.
    @MyAnn
    int x = 0;

    Y y = new Y();
}

class Y {
    @MyAnn
    int y = 1;

    // ...
}

Now, what I need is an iterator over every MyAnn in X, i.e. x and y.y. Imagine I want to print them out:

for (ann : anns) {
    System.out.println(/* annotation */);
}

(Prints out 0, 1).

Basically, there are a few parts of this that I don't know enough Java for:

  • Getting every instance of an annotation
  • Getting the value of an annotated field

Thank you!



Solution 1:[1]

You can scan a class's fields and their annotations via reflection. Here's a basic recursive implementation:

static void scan(Object o) throws IllegalAccessException {
    if (o == null) return;
    
    for (Field field : o.getClass().getDeclaredFields()) {
        if (field.getAnnotation(MyAnn.class) != null) {
            System.out.println(field.get(o));
        }
        if (!field.getType().isPrimitive()) {
            scan(field.get(o));
        }
    }
}

Ideone Demo

This doesn't handle edge cases like inherited fields, private fields and circular references, but it should be enough to get you started.

Solution 2:[2]

Getting every instance of an annotation

MyAnn annotation = field.getAnnotation(MyAnn.class);

And then you can call a property value you have define in your annotation

Getting the value of an annotated field

X instance = new X();
...
field.setAccessible(Boolean.TRUE);
int value= field.getInt(instance);

For the list all annotations, you call the getAnnotations methods. Read about Java Reflection, you will have a good understanding.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 shmosel
Solution 2 Harry Coder