Как обнаружить, что метод (параметр) в подклассе имеет аннотацию, определенную в реализованном интерфейсе? - PullRequest
4 голосов
/ 19 сентября 2011

К сожалению, похоже, что наследование аннотаций строго ограничено тем фактом, что только аннотации уровня классов от классов (а не интерфейсов) могут быть унаследованы.

Рассмотрим этот код:

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

class FooImpl implements Foo {
    void bar(String str, @B int i) { ... }
}

Если у меня есть экземпляр FooImpl, можно ли обнаружить, был ли метод помечен A (либо в классе (легкий), либо в реализованном интерфейсе)?

Как насчет методапараметр?Можно ли наложить на них, если и какой параметр был аннотирован B?

Кажется, что это невозможно с AspectJ, и мне нужно использовать Java Reflection.

Как бы телорешение выглядит?

1 Ответ

3 голосов
/ 19 сентября 2011

Возможно использовать getInterfaces() для объекта класса и запросить результат.

аннотация параметра

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;
}

метод аннотации

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;
}

интерфейс с аннотациями

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

класс с аннотациями и интерфейсом Foo

package mawi12345;
public class Test implements Foo {

    public void setMark(int mark) {

    }

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

Тестовый класс

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);
        }

    }

}

выход

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)
...