@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。