父類上的註解能被子類繼承嗎,接口上面的註解呢

轉載https://www.cnblogs.com/chenkeyu/p/7895751.html

我們知道在編寫自定義註解時,可以通過指定@Inherited註解,指明自定義註解是否可以被繼承,接口的處理方式是否一樣。但實現情況又可細分爲多種。

繼承的方式:

測試環境如下:

父類的類上和方法上有自定義的註解--MyAnnotation

子類繼承了這個父類,分別:

子類方法,實現了父類上的抽象方法

子類方法,繼承了父類上的方法

子類方法,覆蓋了父類上的方法

測試代碼:

public class TestInherited {

    //    @Inherited  //可以被繼承
    @Retention(java.lang.annotation.RetentionPolicy.RUNTIME)   //可以通過反射讀取註解
    public @interface MyAnnotation {
        String value();
    }

    @MyAnnotation(value = "類名上的註解")
    public abstract class ParentClass {

        @MyAnnotation(value = "父類的abstractMethod方法")
        public abstract void abstractMethod();

        @MyAnnotation(value = "父類的doExtends方法")
        public void doExtends() {
            System.out.println(" ParentClass doExtends ...");
        }

        @MyAnnotation(value = "父類的doHandle方法")
        public void doHandle() {
            System.out.println(" ParentClass doHandle ...");
        }
    }

    public class SubClass extends ParentClass {

        //子類實現父類的抽象方法
        @Override
        public void abstractMethod() {
            System.out.println("子類實現父類的abstractMethod抽象方法");
        }

        //子類繼承父類的doExtends方法

        //子類覆蓋父類的doHandle方法
        @Override
        public void doHandle() {
            System.out.println("子類覆蓋父類的doHandle方法");
        }
    }

    public static void main(String[] args) throws SecurityException, NoSuchMethodException {

        Class<SubClass> clazz = SubClass.class;

        if (clazz.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation cla = clazz.getAnnotation(MyAnnotation.class);
            System.out.println("子類繼承到父類類上Annotation,其信息如下:" + cla.value());
        } else {
            System.out.println("子類沒有繼承到父類類上Annotation");
        }

        // 實現抽象方法測試
        Method method = clazz.getMethod("abstractMethod", new Class[]{});
        if (method.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation ma = method.getAnnotation(MyAnnotation.class);
            System.out.println("子類實現父類的abstractMethod抽象方法,繼承到父類抽象方法中的Annotation,其信息如下:" + ma.value());
        } else {
            System.out.println("子類實現父類的abstractMethod抽象方法,沒有繼承到父類抽象方法中的Annotation");
        }

        //繼承測試
        Method methodOverride = clazz.getMethod("doExtends", new Class[]{});
        if (methodOverride.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation ma = methodOverride.getAnnotation(MyAnnotation.class);
            System.out.println("子類繼承父類的doExtends方法,繼承到父類doExtends方法中的Annotation,其信息如下:" + ma.value());
        } else {
            System.out.println("子類繼承父類的doExtends方法,沒有繼承到父類doExtends方法中的Annotation");
        }

        //覆蓋測試
        Method method3 = clazz.getMethod("doHandle", new Class[]{});
        if (method3.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation ma = method3.getAnnotation(MyAnnotation.class);
            System.out.println("子類覆蓋父類的doHandle方法,繼承到父類doHandle方法中的Annotation,其信息如下:" + ma.value());
        } else {
            System.out.println("子類覆蓋父類的doHandle方法,沒有繼承到父類doHandle方法中的Annotation");
        }
    }
}

編寫自定義註解時未寫@Inherited的運行結果

子類沒有繼承到父類類上Annotation
子類實現父類的abstractMethod抽象方法,沒有繼承到父類抽象方法中的Annotation
子類繼承父類的doExtends方法,繼承到父類doExtends方法中的Annotation,其信息如下:父類的doExtends方法
子類覆蓋父類的doHandle方法,沒有繼承到父類doHandle方法中的Annotation

編寫自定義註解時寫了@Inherited的運行結果

子類繼承到父類類上Annotation,其信息如下:類名上的註解
子類實現父類的abstractMethod抽象方法,沒有繼承到父類抽象方法中的Annotation
子類繼承父類的doExtends方法,繼承到父類doExtends方法中的Annotation,其信息如下:父類的doExtends方法
子類覆蓋父類的doHandle方法,沒有繼承到父類doHandle方法中的Annotation

結論

-----------------------------------------------------------------

父類的類上和方法上有自定義的註解,

子類繼承了這個父類,的情況下。

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

 

 

 

 

 

 

 

我們知道在編寫自定義註解時,可以通過指定@Inherited註解,指明自定義註解是否可以被繼承。

通過測試結果來看,@Inherited 只是可控制 對類名上註解是否可以被繼承。不能控制方法上的註解是否可以被繼承。

接口的方式

public class TestInheritedInf {

    //@Inherited  //可以被繼承
    @Retention(java.lang.annotation.RetentionPolicy.RUNTIME)   //可以通過反射讀取註解
    public @interface MyAnnotation {
        String value();
    }

    @MyAnnotation(value = "接口上的註解")
    public interface ParentInf {

        @MyAnnotation(value = "接口的abstractMethod方法")
        void abstractMethod();
    }

    public class SubImpl implements ParentInf {

        //子類實現父類的抽象方法
        @Override
        public void abstractMethod() {
            System.out.println("子類實現接口的abstractMethod抽象方法");
        }
    }

    public static void main(String[] args) throws Exception {

        Class<SubImpl> clazz = SubImpl.class;
        
        Class[] i = clazz.getInterfaces();
        for (Class clz : i) {
            if(clz.isAnnotationPresent(MyAnnotation.class)){
                MyAnnotation w = (MyAnnotation)clz.getAnnotation(MyAnnotation.class);
                System.out.println("value:" + w.value());
            }

            Method[] methods = clz.getMethods();
            for (Method method : methods) {
                if (method.isAnnotationPresent(MyAnnotation.class)) {
                    MyAnnotation w = method.getAnnotation(MyAnnotation.class);
                    System.out.println("value:" + w.value());
                }
            }
        }
    }
}

編寫自定義註解時未寫@Inherited的運行結果

value:接口上的註解
value:接口的abstractMethod方法

編寫自定義註解時寫了@Inherited的運行結果

value:接口上的註解
value:接口的abstractMethod方法

結論:實現類不管加不加@Inherited都能讀取到定義接口的接口或者方法上面的註解

順便說下,如果實現的多個接口聲明瞭同樣的方法,實現類只要實現一次就可以了,然後每個接口都能調用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章