@Inherited注解標記其他的注解用於指明標記的注解是可以被自動繼承的。
注意:此注解只對注解標記的超類有效,對接口是無效的。
示例:
先聲明兩個用@Inherited標記的注解,@Name和@Abbreviation,一個沒有用@Inherited標記的注解@UpperCaseName
package org.springmorning.demo.javabase.annotation.meta; import java.lang.annotation.*; /** * @author 春晨 * @date 2019/1/14 15:49 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Name { //名稱 String value(); }
package org.springmorning.demo.javabase.annotation.meta; import java.lang.annotation.*; /** * @author 春晨 * @date 2019/1/14 14:59 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Abbreviation { //簡稱 String value(); }
package org.springmorning.demo.javabase.annotation.meta; import java.lang.annotation.*; /** * @author 春晨 * @date 2019/1/14 11:19 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface UpperCaseName { //大寫英文名稱 String value(); }
接下來,我們聲明一些接口和類用於舉例,這些類的繼承關系如下:
package org.springmorning.demo.javabase.annotation.meta; /** * @author 春晨 * @date 2019/1/14 15:57 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ @UpperCaseName("ORGANISM") @Abbreviation("Ogm") @Name("Organism") public interface Organism { }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 春晨 * @date 2019/1/14 15:24 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ public interface Plant extends Organism{ }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 春晨 * @date 2019/1/14 15:30 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ @UpperCaseName("FLOWER") @Abbreviation("Flr") @Name("Flower") public abstract class Flower implements Plant { }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 春晨 * @date 2019/1/14 16:00 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ public class Rose extends Flower { }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 春晨 * @date 2019/1/14 11:25 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ @UpperCaseName("ANIMAL") @Abbreviation("Ani") @Name("Animal") public interface Animal extends Organism{ }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 春晨 * @date 2019/1/14 11:30 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ public abstract class Mammal implements Animal { }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 春晨 * @date 2019/1/14 11:34 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ @UpperCaseName("MONKEY") @Abbreviation("Mky") @Name("Monkey") public class Monkey extends Mammal{ }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 春晨 * @date 2019/1/14 16:26 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ @Name("Roxellanae") public class Roxellanae extends Monkey { }
以下我們創建一個測試類:
package org.springmorning.demo.javabase.annotation.meta; import java.lang.annotation.Annotation; /** * @author 春晨 * @date 2019/1/14 11:39 * Copyright ©2019 春晨 https://www.cnblogs.com/springmorning/p/10268727.html */ public class InheritedAnnotation { public static void main(String[] args){ Annotation[] annotations = Plant.class.getAnnotations(); System.out.print("Plant接口繼承Organism接口,在Organism接口上標記的注解,Plant獲取不到:"); for (Annotation annotation : annotations){ System.out.print(annotation.toString()+" "); } annotations = Mammal.class.getAnnotations(); System.out.print("\nMamanl抽象類實現Animal接口,在Animal接口上標記的注解,Mammal獲取不到:"); for (Annotation annotation : annotations){ System.out.print(annotation.toString()+" "); } annotations = Rose.class.getAnnotations(); System.out.print("\nRose類繼承Flower抽象類,在Flower抽象類上標記的注解,如果注解是被@Inherited標記的,都可以獲取到:"); for (Annotation annotation : annotations){ System.out.print(annotation.toString()+" "); } annotations = Roxellanae.class.getAnnotations(); System.out.print("\nRoxellanae類繼承Monkey類,在Monkey抽象類上標記的注解,如果注解是被@Inherited標記的,都可以獲取到;如果被@Inherited標記的注解父類和子類重復標記,則返回子類的注解:"); for (Annotation annotation : annotations){ System.out.print(annotation.toString()+" "); } } }
輸出結果:
Plant接口繼承Organism接口,在Organism接口上標記的注解,Plant獲取不到: Mamanl抽象類實現Animal接口,在Animal接口上標記的注解,Mammal獲取不到: Rose類繼承Flower抽象類,在Flower抽象類上標記的注解,如果注解是被@Inherited標記的,都可以獲取到:@org.springmorning.demo.javabase.annotation.meta.Abbreviation(value=Flr) @org.springmorning.demo.javabase.annotation.meta.Name(value=Flower) Roxellanae類繼承Monkey類,在Monkey抽象類上標記的注解,如果注解是被@Inherited標記的,都可以獲取到;如果被@Inherited標記的注解父類和子類重復標記,則返回子類的注解:@org.springmorning.demo.javabase.annotation.meta.Abbreviation(value=Mky) @org.springmorning.demo.javabase.annotation.meta.Name(value=Roxellanae)
通過運行結果我們可以得出如下三點結論:
- 沒有被@Inherited注解標記的注解,例如上例中的@UpperCaseName注解,就不具有繼承特性,在子類中獲取不到父類的注解;
- @Inherited注解繼承概念跟我們理解的面向對象繼承概念不一樣,它只作用於子類與父類之間的繼承,像上例的Rose類就從Flower父類中繼承了@Abbreviation和@Name注解;對於接口之間的繼承和類與接口之間的實現,這兩種繼承關系不起作用,像上例中Plant接口繼承Organism接口、Mamanl類實現Animal接口,就沒能繼承@Abbreviation和@Name注解;
- @Inherited注解標記的注解,在使用時,如果父類和子類都使用的注解是同一個,那么子類的注解會覆蓋父類的注解,如上例中Roxellanae類用@Name注解標記了,Monkey類也用@Name注解標記了,那么Roxellanae類注解,會覆蓋Monkey的@Name注解。
下節繼續
下節將給大家講解元注解@Repeatable的使用