I am playing around with Java (javax) annotation processing.
Suppose I have an annotation for methods:
@Target(ElementType.METHOD)
public @interface MethodAnnotation { }
Now I want to process all the methods which are overridden from a type with the annotated method:
interface MyInterface() {
@MethodAnnotation
void f()
}
class MyClass implements MyInterface {
override void f() { } // <- I want to process this method
}
@Inherited
meta-annotation seems not to be suitable here:
Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class.
Also, is it possible to process an inherited class method which is not overridden in a subclass? Like this:
class MyClass {
@MethodAnnotation
void f() { }
}
class MySubClass extends MyClass { } // <- I want to process its f()
// or at least to find out that it doesn't
// override the method
How can I access the overriden methods of a certain method within AbstractProcessor
?
I guess, to achieve this I need to find subclasses of the eclosing class, but I haven't found a way to do this either.
UPD: I suppose it's possible using RoundEnvironment.getRootElements()
but still found no proper way of doing this.
Our annotation processor will catch all these Todo annotations at compile time and fails the compilation. This will help developers to either implement this method or if it is already implemented then developer should remove it so the compilation will succeed.
This annotation acts like tagging. We will go through below steps to create and process annotations: Create a new java file Todo.java to declare an annotation. Annotation declaration looks similar to interface except the keyword interface is preceded with @ Todo annotation is declared with two meta-annotations.
This class provides a Messager which can be used to indicate errors in the annotation processing. In this case we printed the error message which contains value of the Todo annotation and the method name on which it is used. <9> true is returned to mention that we complemented our processing.
Annotations do not change the action of a compiled program. Annotations help to associate metadata (information) to the program elements i.e. instance variables, constructors, methods, classes, etc. Annotations are not pure comments as they can change the way a program is treated by the compiler.
The short answer is that out-of-the-box annotation processing isn't going to make this easy for you, but it can be done.
Rather than using the normal dispatch mechanism for processing, you're actually going to have to process every method and do the filtering yourself.
Define your processor so that it supports all annotations by using "*"
as its supported annotation type. This will mean that your processor will get invoked every round.
Use getRootElements
to get the entire set of elements every round.
Create an ElementScanner8
to traverse any element that you find to look for ExecutableElement
s. If you're willing to trust that overridden methods are annotated with @Override
, you can do a quick filter on those. Otherwise, just look at all of them.
Now you need to see if the method overrides a method with the annotation you're looking for. There's no easy way to get methods that a given method has overridden, so you need to get the enclosing element of the method, look at its superclass and implemented interfaces (recursively), get their enclosed elements, filter out the methods, and test to see if it has been overridden by the method in question. If it has, you can check the annotations to see if it has one you care about.
At this point, you should have the overriding method, the overridden method and the annotation mirror that you were looking for, so you should be able to implement whatever logic you wanted.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With