那些高端、优雅的注解是怎么实现的 - 可继承性@Inherited

这是一个看起来让人迷糊的特性,所以我拿出一个章节来说明,然而它并没有那么重要。

自定义注解系列文章

父类Animal

父类Animal 类声明上添加了注解 @Message, getName方法上添加了注解@Message,为什么这么做卖个关子。

/**
 * Created by tuoanlan on 2019/9/26.
 */
@Message(decr = "动物类的描述", author = "zhang", age = 28)
public class Animal {
    String name;
    String age;

    @Message(decr = "获取动物名称的方法", author = "zhang", age = 28)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

子类 Dog

Dog 上没有任何注解,如下。

public class Dog extends Animal{

    String name;
    String age;

    @Override

    public String getName() {
        return name;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String getAge() {
        return age;
    }

    @Override
    public void setAge(String age) {
        this.age = age;
    }
}

调用上面的解析方法打印结果如下

类的描述为:动物类的描述,作者:zhang

说明继承的是类的继承 。而不是方法注解的继承。

为什么接口声明时候注解不能被继承

先看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 {
}

用来指明该注解是能自动继承的那种注解。当声明一个注解的时候使用了@Inherited,那么该注解就是可以自动继承的,我们说该注解具有可继承性(后面说的该注解,都指现在声明的这个注解)。编译器查找这个注解的时候,不仅查找类声明的时候使用了该注解的类,还会去查找类声明的时候没有使用该注解那种类的父类。重复这个过程一直到查找到这个注解或到了顶级父类(object)才会停止。那种所有父类中都没有该注解的类就被认为没有该注解。
注意这种类型的注解(使用了@Inherited的这种类型的注解)的自动继承特性只在当这个注解用到类声明的时候才有有效,其他都不生效。包含@Inherited的类型的那种注解可以从父类继承到子类,但对接口无效,也就是说即使接口上的使用了具有继承性的注解,在他的实现类中,也无法继承到该注解。

总结

这个知识点虽然小,但比较绕,不过理解了就比较简单了.

点赞