开发者

How to discover if a method (parameter) in a subclass has an annotation defined in the implemented interface?

开发者 https://www.devze.com 2023-04-06 08:48 出处:网络
Unfortunately it seems that annotation inheritance is severely restricted by the fact that only class-level annotations from classes (and not interfaces) can be inherited.

Unfortunately it seems that annotation inheritance is severely restricted by the fact that only class-level annotations from classes (and not interfaces) can be inherited.

Consider this code:

interface Foo {
    @A
    void bar(String str, @B int i);
}

class FooImpl implements Foo {
    void bar(String str, @B int i) { ... }开发者_如何学运维
}

If I have an instance of FooImpl is it possible to discover if the method has been annotated with A (either in the class (easy) or in the implemented interface)?

What about the method parameter? Is it possible to dicover if and which parameter has been annotated with B?

It seems that this is not possible with AspectJ and I need to use Java Reflection.

How would a solid solution look like?


Its possible use getInterfaces() on the class object and query the result.

parameter annotation

package mawi12345;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface B {
    int version() default 0;
}

method annotation

package mawi12345;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface Revision {
    int minor() default 0;
    int major() default 1;
}

interface with annotations

package mawi12345;
public interface Foo {
    @Revision(minor=1, major=3)
    public void setMark(@B(version=3) int mark);
}

class with annotations and the Foo interface

package mawi12345;
public class Test implements Foo {

    public void setMark(int mark) {

    }

    @Revision(minor=2, major=4)
    public boolean isPassed() {
        return true;
    }
}

Test Class

package mawi12345;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class ReflectionTest {

    public static void printAnnotations(Class<?> clazz) {
        // array of methods
        Method[] methods = clazz.getDeclaredMethods();
        System.out.println("found "+methods.length+" methods");
        for (int i=0; i<methods.length; i++) {
            // get the annotations of this method
            Annotation[] methodAnnotations = methods[i].getAnnotations();
            // if you only wont to check for one annotation use getAnnotation(Class<T>)

            for (Annotation methodAnnotation : methodAnnotations) {
                System.out.println(methodAnnotation);
            }
            // get the parameter annotations (2d array) 
            Annotation[][] parameterAnnotations = methods[i].getParameterAnnotations();
            // get an array of parameters
            Class<?>[] parameters = methods[i].getParameterTypes();
            for(int x=0; x<parameterAnnotations.length; x++) {
                Class<?> parameter = parameters[x];
                for(Annotation annotation : parameterAnnotations[x]){
                    // print the parameter name and his annotation
                    System.out.println(parameter.getName() + " " + annotation);
                }
            }
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // create Test object
        Test test = new Test();
        // get the class
        Class<?> clazz = test.getClass();
        System.out.println("Class Test");
        // print annotations
        printAnnotations(clazz);
        System.out.println();

        // get the interfaces of the class
        Class<?>[] interfaces = clazz.getInterfaces();

        System.out.println("found "+interfaces.length+" interfaces");
        // print annotations for each interface
        for (Class<?> type : interfaces) {
            System.out.println(type);
            printAnnotations(type);
        }

    }

}

Output

Class Test
found 2 methods
@mawi12345.Revision(minor=2, major=4)

found 1 interfaces
interface mawi12345.Foo
found 1 methods
@mawi12345.Revision(minor=1, major=3)
int @mawi12345.B(version=3)
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号