0

Is it possible to receive annotation value inside a field, that was annotated? Imagine that I have this interface:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
    String value();
}

And I have such implementation:

class SomeClass {
    @MyAnnotation("Annotation")
    private MyClass myClass;
}

What I want to understand is: is it possible to receive value of MyAnnotation inside MyClass? I want to implement a method inside class MyClass, which will return a value of assigned annotation. So, that myClass.getAssignedAnnotationValue() will return "Annotation". If it is not possible, please inform me.

K. Khanda
  • 550
  • 4
  • 11
  • Possible duplicate of [Is it possible to read the value of a annotation in java?](http://stackoverflow.com/questions/4296910/is-it-possible-to-read-the-value-of-a-annotation-in-java) – pvpkiran May 22 '17 at 12:09
  • No, it is not I am asking, is it possible to know annotation value inside annotated field. – K. Khanda May 22 '17 at 12:23

2 Answers2

1

is it possible to know annotation value inside annotated field

It's not possible.

You may have 2 different classes

class SomeClass {
    @MyAnnotation("Annotation")
    private MyClass myClass;
    public SomeClass(MyClass myClass) {
        this.myClass=myClass;
    }
}

and

class SomeClassNo Annotation {
    private MyClass myClass;
    public SomeClassNo(MyClass myClass) {
        this.myClass=myClass;
    }
}

Then you create an instance of MyClass

MyClass instance = new MyClass();

then 2 classes instances new SomeClass(instance) and new SomeClassNo(instance) both have reference to the same instance. So the instance does not know whether the reference field annotated or not.

The only case when it is possible is to pass somehow the container reference to MyClass.

StanislavL
  • 56,971
  • 9
  • 68
  • 98
  • Thank you for the explanation – K. Khanda May 22 '17 at 12:41
  • You don’t even need a second class to show the ambiguity. A `MyClass` instance may live an arbitrary long time before it gets assigned to the annotated `SomeClass.myClass` field. Or it may be referenced by the annotated field for some time, before it gets reassigned, so the object is not referenced by the annotated field anymore. Being referenced is not a property of the object… – Holger May 22 '17 at 17:50
0

There is no straight forward way of implementing what you are asking.

WorkAround:

Limitations:

  1. This workaround doesn't enforce any kind of compile time check and it is completely your responsibility to handle it.
  2. This only works if MyClass is going to be a spring bean.

class MyClass {
    public String annotatedValue;
}

You can write a Spring BeanPostProcessor the following way.

public class SampleBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName)
        throws BeansException {

        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName)
        throws BeansException {

        Field[] fields = bean.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (field instanceof MyClass && field.isAnnotationPresent(MyAnnotation.class)) {
                String value = field.getDeclaredAnnotation(MyAnnotation.class).value();
                ((MyClass) field).annotatedValue = value;
                return bean;
            }
        }
        return bean;
    }
}

The above BeanPostProcessor will be called for every bean during the app start up. It will check all the fields of a given bean to see if the field is of type MyClass. If it is, it will extract the value from the annotation and set it in the annotatedValue field.

The problem with this approach is that you can use MyAnnotation on any property in any class. You cannot enforce the annotation to be used only on MyClass.

yaswanth
  • 2,349
  • 1
  • 23
  • 33