事情的经过是,某天突然对注解继承有点兴趣,于是面向搜索引擎准备解惑下,发现网上都是自己写的例子然后给出结论,而且例子也没有完全覆盖一些情况。于是翻找Java源码得出了以下的输出。
Inherited 类是元注解类,只能修饰注解。
英文说明的第一大段大致意思是:会沿着子类一直找到Object类,把标记为@Inherited的注解信息全部拿到。简单来说标记为@Inherited注解的父类,注解信息就会继承到子类。
第二大段是说:该@Inherited只有标记类的时候才有效果。而且该注解只对父类上的注解有效果,对父接口上的注解是没有效果滴。
/**
* Indicates that an annotation type is automatically inherited. If
* an Inherited meta-annotation is present on an annotation type
* declaration, and the user queries the annotation type on a class
* declaration, and the class declaration has no annotation for this type,
* then the class's superclass will automatically be queried for the
* annotation type. This process will be repeated until an annotation for this
* type is found, or the top of the class hierarchy (Object)
* is reached. If no superclass has an annotation for this type, then
* the query will indicate that the class in question has no such annotation.
*
* <p>Note that this meta-annotation type has no effect if the annotated
* type is used to annotate anything other than a class. Note also
* that this meta-annotation only causes annotations to be inherited
* from superclasses; annotations on implemented interfaces have no
* effect.
*
* @author Joshua Bloch
* @since 1.5
* @jls 9.6.3.3 @Inherited
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
如果,同学只想要一个结果,那么看到这里就足够了。因为接下来要分析为什么会这样。
准备工作需要自定义一个注解:
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 自定义注解,参考{@link javax.annotation.Resource}
*
* @author <a href="wupeng6684@163.com">pengwu</a>
* @since
**/
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
//@Inherited // 开启之后只是影响 if (AnnotationType.getInstance(annotationClass).isInherited()) 判断而已
public @interface MyAnnotation {
String name() default "";
}
为了覆盖所有情况,准备一个接口、一个抽象类、一个普通类
@MyAnnotation(name = "myInterface")
public interface MyInterface {
@MyAnnotation(name = "myInterface-overrideMethod")
void overrideMethod();
@MyAnnotation(name = "myInterface-method")
default void method() {
}
}
@MyAnnotation(name = "myAbstractClazz")
public abstract class MyAbstractClazz {
@MyAnnotation(name = "myAbstractClazz-method")
public void method() {
}
@MyAnnotation(name = "myAbstractClazz-overrideMethod")
public abstract void overrideMethod();
}