方法注释继承

时间:2017-07-28 09:08:42

标签: java inheritance methods annotations

所以,我的问题如下,我使用注释来标记类的方法。

我的主要注释是@Action,我需要为@SpecificAction的特定方法提供更强的注释。

所有使用@SpecificAction注释的方法都必须注释为@Action。 我的想法是@SpecificAction注明@Action

@Action
[other irrelevant annotations]
public @interface SpecificAction{}

@SpecificAction
public void specificMethod(){}

我希望specificMethod.isAnnotationPresent(Action.class)是真的,但它不是。

我怎样才能使@Action注释被"继承"?

1 个答案:

答案 0 :(得分:3)

正如@ assylias的链接所说,注释无法继承,但您可以使用合成,并递归搜索您的目标注释,如下所示:

public static class AnnotationUtil {

    private static <T extends Annotation> boolean containsAnnotation(Class<? extends Annotation> annotation, Class<T> annotationTypeTarget, Set<Class<? extends Annotation>> revised) {
        boolean result = !revised.contains(annotation);
        if (result && annotationTypeTarget != annotation) {
            Set<Class<? extends Annotation>> nextRevised = new HashSet<>(revised);
            nextRevised.add(annotation);
            result = Arrays.stream(annotation.getAnnotations()).anyMatch(a -> containsAnnotation(a.annotationType(), annotationTypeTarget, nextRevised));
        }
        return result;
    }

    public static <T extends Annotation> boolean containsAnnotation(Class<? extends Annotation> annotation, Class<T> annotationTypeTarget) {
        return containsAnnotation(annotation, annotationTypeTarget, Collections.emptySet());
    }

    public static <T extends Annotation> Map<Class<? extends Annotation>, ? extends Annotation> getAnnotations(Method method, Class<T> annotationTypeTarget) {
        return Arrays.stream(method.getAnnotations()).filter(a -> containsAnnotation(a.annotationType(), annotationTypeTarget)).collect(Collectors.toMap(a -> a.annotationType(), Function.identity()));
    }
}

如果你有:

@Retention(RetentionPolicy.RUNTIME)
@interface Action {
}

@Action
@Retention(RetentionPolicy.RUNTIME)
@interface SpecificAction {
}

@Action
@Retention(RetentionPolicy.RUNTIME)
@interface ParticularAction {
}

public class Foo{
    @SpecificAction
    @ParticularAction
    public void specificMethod() {
         // ...
    }
}

你可以这样使用:AnnotationUtil.getAnnotations(specificMethod, Action.class);这将返回一张地图:{interface foo.ParticularAction=@foo.ParticularAction(), interface foo.SpecificAction=@foo.SpecificAction()}