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