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。

posted on 2013-11-25 12:51  duanxz  阅读(5342)  评论(2编辑  收藏  举报