@Inherited
-
元注解:标记在注解上方,作用于被标记的注解@Template,类似@Inherited的注解称为元注解。
@Inherited public @interface Template{ }
-
作用: 被标记的注解@Template,是可以被自动继承的,但仅限于类与类之间的继承。
以下示例来源于网络:春晨编辑的《@Inherited元注解的使用》
举例:
- 使用@Inherited定义注解:@Name和@Abbreviation
- 没有用@Inherited标记的注解@UpperCaseName
/**
* 注解一: 名称
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Name {
//名称
String value();
}
/**
* 注解二: 名称缩写
*/
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Abbreviation {
//简称
String value();
}
/**
* 注解三: 大写的名称
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface UpperCaseName {
//大写英文名称
String value();
}
以上三种注解的使用
/**
* 顶层接口:生物
*/
@UpperCaseName("ORGANISM")
@Abbreviation("Ogm")
@Name("Organism")
public interface Organism {
}
/**
* 分接口:植物
*/
public interface Plant extends Organism{
}
/**
* 分接口抽象类:花
*/
@UpperCaseName("FLOWER")
@Abbreviation("Flr")
@Name("Flower")
public abstract class Flower implements Plant {
}
/**
* 实现类:玫瑰花
*/
public class Rose extends Flower {
}
/**
* 分接口:植物
*/
@UpperCaseName("ANIMAL")
@Abbreviation("Ani")
@Name("Animal")
public interface Animal extends Organism{
}
/**
* 分接口抽象类:花
*/
public abstract class Mammal implements Animal {
}
/**
* 实现类:玫瑰花
*/
@UpperCaseName("MONKEY")
@Abbreviation("Mky")
@Name("Monkey")
public class Monkey extends Mammal{
}
/**
* 实现类:玫瑰花
*/
@Name("Roxellanae")
public class Roxellanae extends Monkey {
}
测试类
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标记的,都可以获取到:
@com.wiseco.local.test.inherited.anno.Abbreviation(value=Flr)
@com.wiseco.local.test.inherited.anno.Name(value=Flower)
Roxellanae类继承Monkey类,在Monkey抽象类上标记的注解,如果注解是被@Inherited标记的,都可以获取到;如果被@Inherited标记的注解父类和子类重复标记,则返回子类的注解:
@com.wiseco.local.test.inherited.anno.Abbreviation(value=Mky)
@com.wiseco.local.test.inherited.anno.Name(value=Roxellanae)
图示
结论
通过运行结果我们可以得出如下三点:
- 没有被@Inherited注解标记的注解,例如上例中的@UpperCaseName注解,就不具有继承特性,在子类中获取不到父类的注解;
- @Inherited注解继承概念跟我们理解的面向对象继承概念不一样,它只作用于子类与父类之间的继承,像上例的Rose类就从Flower父类中继承了@Abbreviation和@Name注解;对于接口之间的继承和类与接口之间的实现,这两种继承关系不起作用,像上例中Plant接口继承Organism接口、Mamanl类实现Animal接口,就没能继承@Abbreviation和@Name注解;
- @Inherited注解标记的注解,在使用时,如果父类和子类都使用的注解是同一个,那么子类的注解会覆盖父类的注解,如上例中Roxellanae类用@Name注解标记了,Monkey类也用@Name注解标记了,那么Roxellanae类注解,会覆盖Monkey的@Name注解。