Annotation之二:@Inherited注解繼承情況


@Inherited annotation類型是被標注過的class的子類所繼承。類並不從它所實現的接口繼承annotation,方法並不從它所重載的方法繼承annotation

子類中能否繼承注解如下:(類和接口情況)

 

上面的結果同樣適用子類的子類。

示例1:自定義注解標記在類上的繼承情況

1、自定義注解

package com.dxz.annotation.demo;

import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;

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

2、被注解的父類

package com.dxz.annotation.demo;

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

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

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

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

子類:

package com.dxz.annotation.demo;

public class SubClass1 extends ParentClass {

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

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

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

測試類:

package com.dxz.annotation.demo;

import java.lang.reflect.Method;

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

        Class<SubClass1> clazz = SubClass1.class;

        if (clazz.isAnnotationPresent(BatchExec.class)) {
            BatchExec cla = clazz.getAnnotation(BatchExec.class);
            System.out.println("類:子類可繼承,注解讀取='" + cla.value() + "'");
        } else {
            System.out.println("類:子類不能繼承到父類類上Annotation");
        }

        // 實現抽象方法測試
        Method method = clazz.getMethod("abstractMethod", new Class[] {});
        if (method.isAnnotationPresent(BatchExec.class)) {
            BatchExec ma = method.getAnnotation(BatchExec.class);
            System.out.println("子類實現抽象方法:子類可繼承,注解讀取='" + ma.value() + "'");
        } else {
            System.out.println("子類實現抽象方法:沒有繼承到父類抽象方法中的Annotation");
        }

        // 子類未重寫的方法
        Method methodOverride = clazz.getMethod("doExtends", new Class[] {});
        if (methodOverride.isAnnotationPresent(BatchExec.class)) {
            BatchExec ma = methodOverride.getAnnotation(BatchExec.class);
            System.out.println("子類未實現方法:子類可繼承,注解讀取='" + ma.value() + "'");
        } else {
            System.out.println("子類未實現方法:沒有繼承到父類doExtends方法中的Annotation");
        }

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

        // 子類重寫的方法
        Method method4 = clazz.getMethod("doHandle2", new Class[] {});
        if (method4.isAnnotationPresent(BatchExec.class)) {
            BatchExec ma = method4.getAnnotation(BatchExec.class);
            System.out.println("子類未實現方法doHandle2:子類可繼承,注解讀取='" + ma.value());
        } else {
            System.out.println("子類未實現方法doHandle2:沒有繼承到父類doHandle2方法中的Annotation");
        }
    }
}

結果:

類:子類可繼承,注解讀取='類名上的注解'--場景2
子類實現抽象方法:沒有繼承到父類抽象方法中的Annotation--場景4
子類未實現方法:子類可繼承,注解讀取='父類的doExtends方法'--場景6
子類覆蓋父類的方法:沒有繼承到父類doHandle方法中的Annotation--場景8
子類未實現方法doHandle2:沒有繼承到父類doHandle2方法中的Annotation--場景5

 

示例2:自定義注解標記在接口上的繼承情況

package com.dxz.annotation.demo3;

@BatchExec(value = "接口上的注解")
public interface Parent {
    void abstractMethod();
}

接口的繼承類

package com.dxz.annotation.demo3;

import com.dxz.annotation.BatchExec;

///@BatchExec(value = "類名上的注解")
public abstract class ParentClass3  {

    public void abstractMethod() {
        System.out.println("ParentClass3");    
    }

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

該繼承類的注解可見測試:

package com.dxz.annotation.demo3;

import java.lang.reflect.Method;

import com.dxz.annotation.BatchExec;

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

        Class<ParentClass3> clazz = ParentClass3.class;

        if (clazz.isAnnotationPresent(BatchExec.class)) {
            BatchExec cla = clazz.getAnnotation(BatchExec.class);
            System.out.println("類:子類可繼承,注解讀取='" + cla.value()+"'");
        } else {
            System.out.println("類:子類不能繼承到接口類上Annotation");
        }

        // 實現抽象方法測試
        Method method = clazz.getMethod("abstractMethod", new Class[] {});
        if (method.isAnnotationPresent(BatchExec.class)) {
            BatchExec ma = method.getAnnotation(BatchExec.class);
            System.out.println("子類實現抽象方法:子類可繼承,注解讀取='" + ma.value()+"'");
        } else { 
            System.out.println("子類實現抽象方法:沒有繼承到接口抽象方法中的Annotation");
        }

        //子類中新增方法
        Method methodOverride = clazz.getMethod("doExtends", new Class[] {});
        if (methodOverride.isAnnotationPresent(BatchExec.class)) {
            BatchExec ma = methodOverride.getAnnotation(BatchExec.class);
            System.out.println("子類中新增方法:注解讀取='" + ma.value()+"'");
        } else {
            System.out.println("子類中新增方法:不能讀取注解");
        }

    }
}

結果:

類:子類不能繼承到接口類上Annotation--場景12
子類實現抽象方法:沒有繼承到接口抽象方法中的Annotation--場景14
子類中新增方法:注解讀取='父類中新增的doExtends方法'--場景16

子類的子類注解繼承情況:

package com.dxz.annotation.demo3;

public class SubClass3 extends ParentClass3 {

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

    // 子類覆蓋父類的doExtends方法
}

測試類:

package com.dxz.annotation.demo3;

import java.lang.reflect.Method;

import com.dxz.annotation.BatchExec;

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

        Class<SubClass3> clazz = SubClass3.class;

        if (clazz.isAnnotationPresent(BatchExec.class)) {
            BatchExec cla = clazz.getAnnotation(BatchExec.class);
            System.out.println("類:子類可繼承,注解讀取='" + cla.value()+"'");
        } else {
            System.out.println("類:子類不能繼承到父類類上Annotation");
        }

        // 實現抽象方法測試
        Method method = clazz.getMethod("abstractMethod", new Class[] {});
        if (method.isAnnotationPresent(BatchExec.class)) {
            BatchExec ma = method.getAnnotation(BatchExec.class);
            System.out.println("子類實現抽象方法:子類可繼承,注解讀取='" + ma.value()+"'");
        } else { 
            System.out.println("子類實現抽象方法:沒有繼承到父類抽象方法中的Annotation");
        }

        //子類未重寫的方法
        Method methodOverride = clazz.getMethod("doExtends", new Class[] {});
        if (methodOverride.isAnnotationPresent(BatchExec.class)) {
            BatchExec ma = methodOverride.getAnnotation(BatchExec.class);
            System.out.println("子類未實現方法:子類可繼承,注解讀取='" + ma.value()+"'");
        } else {
            System.out.println("子類未實現方法:沒有繼承到父類doExtends方法中的Annotation");
        }

    }
}

結果:

類:子類不能繼承到父類類上Annotation
子類實現抽象方法:沒有繼承到父類抽象方法中的Annotation--場景14
子類未實現方法:子類可繼承,注解讀取='父類中新增的doExtends方法'--場景18

 

 

附注

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

Spring 實現事務的注解@Transactional 是可以被繼承的,

通過查看它的源碼可以看到@Inherited。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM