【问题标题】:Method annotation inheritance方法注解继承
【发布时间】:2018-01-04 06:42:09
【问题描述】:

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

我的主要注解是@Action,我需要一个更强大的注解来用于特定方法,即@SpecificAction。

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

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

与

@SpecificAction
public void specificMethod(){}

我希望specificMethod.isAnnotationPresent(Action.class) 是真的,但事实并非如此。

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

【问题讨论】:

  • @Action @SpecificAction public void specificMethod(){}
  • 您可以通过在注释中添加诸如String type() default "base"; 或boolean isSpecific default false; 之类的属性来解决此问题。
  • @Michael 那是我不想做的(我很懒:))
  • @MickMnemonic 这就是我所做的,但我有点难过我不能拥有那个“继承:p”

标签: java inheritance methods annotations


【解决方案1】:

正如@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()}

【讨论】:

  • 这个想法确实闪过我的脑海,我正在寻找一种方法来避免这样做并且不必编写递归。但是正如链接中所说,很高兴知道没有这样的继承!
猜你喜欢
  • 2012-09-07
  • 2011-11-02
  • 2015-08-06
  • 1970-01-01
  • 1970-01-01
  • 2017-06-04
  • 2017-12-19
  • 2011-03-31
  • 1970-01-01
相关资源
最近更新 更多