當前位置:網站首頁>@Inherit注解與注解的繼承

@Inherit注解與注解的繼承

2022-01-27 23:12:15 1379號監聽猿

引言

父類上的注解能否被子類繼承,怎樣才能被子類繼承?父類方法上的注解呢?

驗證

先定義一個注解

@Inherited
@Retention(RUNTIME)   // 可以通過反射讀取注解
public @interface MyInheritedAnnotation {
    
    String value() ;
}

然後定義父類,類上和方法上都標注有MyInheritedAnnotation注解

@MyInheritedAnnotation("father class")
public abstract class Father {
    
    @MyInheritedAnnotation("覆蓋")
    public void f1() {
    }

    @MyInheritedAnnotation("繼承")
    public void f2() {
    }

    @MyInheritedAnnotation("子類實現抽象方法")
    public abstract void abstractFunction();
}

再定義子類,實現父類的抽象方法abstractFunction,覆蓋父類的f1,繼承父類的f2

public class Son extends Father {
    
    @Override
    public void f1() {
    }

    @Override
    public void abstractFunction() {
    }
}

最後寫一個測試類:

public class InheritedTest {
    
    public static void main(String[] args) {
    
        System.out.println("************** Father ****************");
        getClassAnnotations(Father.class);
        Method[] methods = Father.class.getMethods();
        for (int i = 0; i < methods.length; i++) {
    
            getMethodAnnotations(methods[i]);
        }

        System.out.println("**************** Son *****************");
        getClassAnnotations(Son.class);
        methods = Son.class.getMethods();
        for (int i = 0; i < methods.length; i++) {
    
            getMethodAnnotations(methods[i]);
        }
    }

    public static void getClassAnnotations(Class clazz) {
    
        Annotation[] annotations = clazz.getAnnotations();
        for (int i = 0; i < annotations.length; i++) {
    
            System.out.println("類:" + clazz.getName() + "上注解:\t" +
                   (((MyInheritedAnnotation) annotations[i]).value()));
        }
    }

    public static void getMethodAnnotations(Method method) {
    
        Annotation[] annotations = method.getAnnotations();
        for (int i = 0; i < annotations.length; i++) {
    
            System.out.println("方法:" + method.getName() + "上注解:\t" +
                   (((MyInheritedAnnotation) annotations[i]).value()));
        }
    }

}

結果:

************** Father ****************
類:com.seaxll.annotation.inherit.Father上注解:	father class
方法:abstractFunction上注解:	子類實現抽象方法
方法:f2上注解:	繼承
方法:f1上注解:	覆蓋
**************** Son *****************
類:com.seaxll.annotation.inherit.Son上注解:	father class
方法:f2上注解:	繼承

Process finished with exit code 0

然後注釋掉@Inherited注解

// @Inherited
@Retention(RUNTIME)   // 可以通過反射讀取注解
public @interface MyInheritedAnnotation {
    
    String value() ;
}

再運行測試代碼:

************** Father ****************
類:com.seaxll.annotation.inherit.Father上注解:	father class
方法:f1上注解:	覆蓋
方法:f2上注解:	繼承
方法:abstractFunction上注解:	子類實現抽象方法
**************** Son *****************
方法:f2上注解:	繼承

Process finished with exit code 0

結論

從上面的執行結果可以看出:

  • 對於類:當取消@Inherited注解的時候,子類沒有繼承父類類上的MyInheritedAnnotation,即:子類只能繼承父類上有@Inherited注解的注解;
  • 對於方法:
    • 普通繼承:無論注解有不有@Inherited,子類的方法都能繼承父類方法上的注解
    • 抽象實現:無法繼承父類方法上的注解
    • 方法覆蓋:無法繼承父類方法上的注解

即:

  • @Inherited注解只影響類上注解的繼承關系;不影響方法上注解的繼承關系
  • 覆蓋和抽象方法的實現是覆蓋和覆蓋父類的注解

父類的類上和方法上有自定義的注解,子類繼承了這個父類,的情况下,有以下規則:

編寫自定義注解時未寫@Inherited的運行結果: 編寫自定義注解時寫了@Inherited的運行結果:
子類的類上能否繼承到父類的類上的注解?
子類方法,實現了父類上的抽象方法,這個方法能否繼承到注解?
子類方法,繼承了父類上的方法,這個方法能否繼承到注解?
子類方法,覆蓋了父類上的方法,這個方法能否繼承到注解?

版權聲明
本文為[1379號監聽猿]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/01/202201272312150771.html

隨機推薦