Java中有类似Notesition Heritage的东西吗?

2022-08-31 07:57:01

我正在探索注释,并达到了一些注释之间似乎具有层次结构的地步。

我正在使用注释在后台为卡片生成代码。有不同的卡类型(因此有不同的代码和注释),但其中有一些元素是通用的,如名称。

@Target(value = {ElementType.TYPE})
public @interface Move extends Page{
 String method1();
 String method2();
}

这将是常见的注释:

@Target(value = {ElementType.TYPE})
public @interface Page{
 String method3();
}

在上面的示例中,我希望 Move 继承 method3,但我收到一条警告,指出扩展对注释无效。我试图让一个注释扩展一个共同的基础,但这不起作用。这甚至可能,还是只是一个设计问题?


答案 1

您可以使用基本批注而不是继承来批注批注。这在Spring框架中使用

举个例子

@Target(value = {ElementType.ANNOTATION_TYPE})
public @interface Vehicle {
}

@Target(value = {ElementType.TYPE})
@Vehicle
public @interface Car {
}

@Car
class Foo {
}

然后,您可以使用Spring的NotementUtils检查类是否进行了注释:Vehicle

Vehicle vehicleAnnotation = AnnotationUtils.findAnnotation (Foo.class, Vehicle.class);
boolean isAnnotated = vehicleAnnotation != null;

此方法实现为:

public static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType) {
    return findAnnotation(clazz, annotationType, new HashSet<Annotation>());
}

@SuppressWarnings("unchecked")
private static <A extends Annotation> A findAnnotation(Class<?> clazz, Class<A> annotationType, Set<Annotation> visited) {
    try {
        Annotation[] anns = clazz.getDeclaredAnnotations();
        for (Annotation ann : anns) {
            if (ann.annotationType() == annotationType) {
                return (A) ann;
            }
        }
        for (Annotation ann : anns) {
            if (!isInJavaLangAnnotationPackage(ann) && visited.add(ann)) {
                A annotation = findAnnotation(ann.annotationType(), annotationType, visited);
                if (annotation != null) {
                    return annotation;
                }
            }
        }
    }
    catch (Exception ex) {
        handleIntrospectionFailure(clazz, ex);
        return null;
    }

    for (Class<?> ifc : clazz.getInterfaces()) {
        A annotation = findAnnotation(ifc, annotationType, visited);
        if (annotation != null) {
            return annotation;
        }
    }

    Class<?> superclass = clazz.getSuperclass();
    if (superclass == null || Object.class == superclass) {
        return null;
    }
    return findAnnotation(superclass, annotationType, visited);
}

AnnotationUtils 还包含用于搜索方法和其他带批注元素的批注的其他方法。Spring类也足够强大,可以通过桥接方法,代理和其他角落案例进行搜索,特别是在Spring中遇到的那些。


答案 2

很遗憾,没有。显然,它与读取类上的注释而不一直加载它们的程序有关。请参阅为什么在 Java 中无法扩展注释?

但是,如果@Inherited这些批注,则类型确实会继承其超类的批注。

此外,除非需要这些方法进行交互,否则只需将注释堆叠到类上即可:

@Move
@Page
public class myAwesomeClass {}

有什么原因不适合你吗?


推荐