@Inherited:
@Inherited 元註解是一個標記註解,@Inherited闡述了某個被標註的類型是被繼承的。
若是一個使用了@Inherited修飾的annotation類型被用於一個class,則這個annotation將被用於該class的子類。
注意:@Inherited annotation類型是被標註過的class的子類所繼承。類並不從它所實現的接口繼承annotation,
方法並不從它所重載的方法繼承annotation。
當@Inherited annotation類型標註的annotation的Retention是RetentionPolicy.RUNTIME,則反射API加強了這種繼承性。
若是咱們使用java.lang.reflect去查詢一個@Inherited annotation類型的annotation時,反射代碼檢查將展開工做:
檢查class和其父類,直到發現指定的annotation類型被發現,或者到達類繼承結構的頂層。
看下面的例子:
Java代碼
- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- @Inherited
- public @interface ATable {
-
- public String name() default "";
- }
-
- @Target(ElementType.TYPE)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface BTable {
- public String name() default "";
- }
-
-
- @ATable
- public class Super {
- private int superx;
- public int supery;
- public Super() {
- }
- private int superX(){
- return 0;
- }
- public int superY(){
- return 0;
- }
-
- }
-
-
- @BTable
- public class Sub extends Super{
- private int subx;
- public int suby;
- private Sub()
- {
- }
- public Sub(int i){
- }
- private int subX(){
- return 0;
- }
- public int subY(){
- return 0;
- }
- }
-
-
-
- public class TestMain {
- public static void main(String[] args) {
-
- Class<Sub> clazz = Sub.class;
-
- System.out.println("============================Field===========================");
- System.out.println(Arrays.toString(clazz.getFields()));
- System.out.println(Arrays.toString(clazz.getDeclaredFields())); //all + 自身
- System.out.println("============================Method===========================");
- System.out.println(Arrays.toString(clazz.getMethods())); //public + 繼承
- //all + 自身
- System.out.println(Arrays.toString(clazz.getDeclaredMethods()));
- System.out.println("============================Constructor===========================");
- System.out.println(Arrays.toString(clazz.getConstructors()));
- System.out.println(Arrays.toString(clazz.getDeclaredConstructors()));
- System.out.println("============================AnnotatedElement===========================");
- //註解DBTable2是否存在於元素上
- System.out.println(clazz.isAnnotationPresent(BTable.class));
- //若是存在該元素的指定類型的註釋DBTable2,則返回這些註釋,不然返回 null。
- System.out.println(clazz.getAnnotation(BTable.class));
- //繼承
- System.out.println(Arrays.toString(clazz.getAnnotations()));
- System.out.println(Arrays.toString(clazz.getDeclaredAnnotations())); ////自身
- }
- }
分析下這段代碼,這裏定義了兩個annotion,其中ATable使用了@Inherited, BTable沒有使用
@Inherited,類Super和類Sub分別使用了ATable和BTable這兩個註解,而且Sub類 繼承Super類。
這段程序的運行結果以下:
Java代碼
- ============================Field===========================
- [public int annotion.inherit.Sub.suby, public int annotion.inherit.Super.supery]
- [private int annotion.inherit.Sub.subx, public int annotion.inherit.Sub.suby]
- ============================Method===========================
- [public int annotion.inherit.Sub.subY(), public int annotion.inherit.Super.superY(), public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
- [private int annotion.inherit.Sub.subX(), public int annotion.inherit.Sub.subY()]
- ============================Constructor===========================
- [public annotion.inherit.Sub(int)]
- [private annotion.inherit.Sub(), public annotion.inherit.Sub(int)]
- ============================AnnotatedElement===========================
- true
- @annotion.inherit.BTable(name=)
- [@annotion.inherit.ATable(name=), @annotion.inherit.BTable(name=)]
- [@annotion.inherit.BTable(name=)]
getFields()得到某個類的全部的公共(public)的字段,包括父類。
getDeclaredFields()得到某個類的全部申明的字段,即包括public、private和proteced,
可是不包括父類的申明字段。 一樣相似的還有getConstructors()和getDeclaredConstructors(),
getMethods()和getDeclaredMethods()。
所以:Field的打印好理解,由於sub是super類的子類,會繼承super的類
一樣method和constructor的打印也是如此。
clazz.getAnnotations()能夠打印出當前類的註解和父類的註解
clazz.getDeclaredAnnotations()只會打印出當前類的註解
若是註解ATable把@Inherit去掉。那麼後面四行的輸出結果爲:
Java代碼
- true
- @annotion.inherit.BTable(name=)
- [@annotion.inherit.BTable(name=)]
- [@annotion.inherit.BTable(name=)]
沒法獲取到@ATable的註解, 也就是說註解和普通類的區別是若是一個子類想獲取到父類上的註解信息, 那麼必須在父類上使用的註解上面 加上@Inherit關鍵字