JavaSE基础:@Inherited元注解的使用
@Inherited注解标记其他的注解用于指明标记的注解是可以被自动继承的。
注意:此注解只对注解标记的超类有效,对接口是无效的。
示例:
先声明两个用@Inherited标记的注解,@Name和@Abbreviation,一个没有用@Inherited标记的注解@UpperCaseName
package org.springmorning.demo.javabase.annotation.meta; import java.lang.annotation.*; /** * @author 编程老司机 */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Name { //名称 String value(); }
package org.springmorning.demo.javabase.annotation.meta; import java.lang.annotation.*; /** * @author 编程老司机 */ @Inherited @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface Abbreviation { //简称 String value(); }
package org.springmorning.demo.javabase.annotation.meta; import java.lang.annotation.*; /** * @author 编程老司机 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface UpperCaseName { //大写英文名称 String value(); }
接下来,我们声明一些接口和类用于举例,这些类的继承关系如下:
package org.springmorning.demo.javabase.annotation.meta; /** * @author 编程老司机 */ @UpperCaseName("ORGANISM") @Abbreviation("Ogm") @Name("Organism") public interface Organism { }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 编程老司机 */ public interface Plant extends Organism{ }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 编程老司机 */ @UpperCaseName("FLOWER") @Abbreviation("Flr") @Name("Flower") public abstract class Flower implements Plant { }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 编程老司机 */ public class Rose extends Flower { }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 编程老司机 */ @UpperCaseName("ANIMAL") @Abbreviation("Ani") @Name("Animal") public interface Animal extends Organism{ }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 编程老司机 */ public abstract class Mammal implements Animal { }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 编程老司机 */ @UpperCaseName("MONKEY") @Abbreviation("Mky") @Name("Monkey") public class Monkey extends Mammal{ }
package org.springmorning.demo.javabase.annotation.meta; /** * @author 编程老司机 */ @Name("Roxellanae") public class Roxellanae extends Monkey { }
以下我们创建一个测试类:
package org.springmorning.demo.javabase.annotation.meta; import java.lang.annotation.Annotation; /** * @author 编程老司机 */ 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的使用
如果您觉得博文不错,请用微信扫描右上方二维码,关注我的微信公众号“编程老司机”,获取最新推送文章。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端