@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。

子类中能否继承注解如下:(类和接口情况)

上面的结果同样适用子类的子类。

示例1:自定义注解标记在类上的继承情况

1、自定义注解

  1. package com.dxz.annotation.demo;
  2.  
  3. import java.lang.annotation.Inherited;
  4. import java.lang.annotation.Retention;
  5.  
  6. @Inherited // 可以被继承
  7. @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) // 可以通过反射读取注解
  8. public @interface BatchExec {
  9. String value();
  10. }

2、被注解的父类

  1. package com.dxz.annotation.demo;
  2.  
  3. @BatchExec(value = "类名上的注解")
  4. public abstract class ParentClass {
  5.  
  6. @BatchExec(value = "父类的abstractMethod方法")
  7. public abstract void abstractMethod();
  8.  
  9. @BatchExec(value = "父类的doExtends方法")
  10. public void doExtends() {
  11. System.out.println(" ParentClass doExtends ...");
  12. }
  13.  
  14. @BatchExec(value = "父类的doHandle方法")
  15. public void doHandle() {
  16. System.out.println(" ParentClass doHandle ...");
  17. }
  18.  
  19. //@BatchExec(value = "父类的doHandle方法")
  20. public void doHandle2() {
  21. System.out.println(" ParentClass doHandle ...");
  22. }
  23. }

子类:

  1. package com.dxz.annotation.demo;
  2.  
  3. public class SubClass1 extends ParentClass {
  4.  
  5. // 子类实现父类的抽象方法
  6. @Override
  7. public void abstractMethod() {
  8. System.out.println("子类实现父类的abstractMethod抽象方法");
  9. }
  10.  
  11. //子类继承父类的doExtends方法
  12.  
  13. // 子类覆盖父类的doHandle方法
  14. @Override
  15. public void doHandle() {
  16. System.out.println("子类覆盖父类的doHandle方法");
  17. }
  18.  
  19. }

测试类:

  1. package com.dxz.annotation.demo;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. public class MainTest1 {
  6. public static void main(String[] args) throws SecurityException, NoSuchMethodException {
  7.  
  8. Class<SubClass1> clazz = SubClass1.class;
  9.  
  10. if (clazz.isAnnotationPresent(BatchExec.class)) {
  11. BatchExec cla = clazz.getAnnotation(BatchExec.class);
  12. System.out.println("类:子类可继承,注解读取='" + cla.value() + "'");
  13. } else {
  14. System.out.println("类:子类不能继承到父类类上Annotation");
  15. }
  16.  
  17. // 实现抽象方法测试
  18. Method method = clazz.getMethod("abstractMethod", new Class[] {});
  19. if (method.isAnnotationPresent(BatchExec.class)) {
  20. BatchExec ma = method.getAnnotation(BatchExec.class);
  21. System.out.println("子类实现抽象方法:子类可继承,注解读取='" + ma.value() + "'");
  22. } else {
  23. System.out.println("子类实现抽象方法:没有继承到父类抽象方法中的Annotation");
  24. }
  25.  
  26. // 子类未重写的方法
  27. Method methodOverride = clazz.getMethod("doExtends", new Class[] {});
  28. if (methodOverride.isAnnotationPresent(BatchExec.class)) {
  29. BatchExec ma = methodOverride.getAnnotation(BatchExec.class);
  30. System.out.println("子类未实现方法:子类可继承,注解读取='" + ma.value() + "'");
  31. } else {
  32. System.out.println("子类未实现方法:没有继承到父类doExtends方法中的Annotation");
  33. }
  34.  
  35. // 子类重写的方法
  36. Method method3 = clazz.getMethod("doHandle", new Class[] {});
  37. if (method3.isAnnotationPresent(BatchExec.class)) {
  38. BatchExec ma = method3.getAnnotation(BatchExec.class);
  39. System.out.println("子类覆盖父类的方法:继承到父类doHandle方法中的Annotation,其信息如下:" + ma.value());
  40. } else {
  41. System.out.println("子类覆盖父类的方法:没有继承到父类doHandle方法中的Annotation");
  42. }
  43.  
  44. // 子类重写的方法
  45. Method method4 = clazz.getMethod("doHandle2", new Class[] {});
  46. if (method4.isAnnotationPresent(BatchExec.class)) {
  47. BatchExec ma = method4.getAnnotation(BatchExec.class);
  48. System.out.println("子类未实现方法doHandle2:子类可继承,注解读取='" + ma.value());
  49. } else {
  50. System.out.println("子类未实现方法doHandle2:没有继承到父类doHandle2方法中的Annotation");
  51. }
  52. }
  53. }

结果:

  1. 类:子类可继承,注解读取='类名上的注解'--场景2
  2. 子类实现抽象方法:没有继承到父类抽象方法中的Annotation--场景4
  3. 子类未实现方法:子类可继承,注解读取='父类的doExtends方法'--场景6
  4. 子类覆盖父类的方法:没有继承到父类doHandle方法中的Annotation--场景8
  5. 子类未实现方法doHandle2:没有继承到父类doHandle2方法中的Annotation--场景5

示例2:自定义注解标记在接口上的继承情况

  1. package com.dxz.annotation.demo3;
  2.  
  3. @BatchExec(value = "接口上的注解")
  4. public interface Parent {
  5. void abstractMethod();
  6. }

接口的继承类

  1. package com.dxz.annotation.demo3;
  2.  
  3. import com.dxz.annotation.BatchExec;
  4.  
  5. ///@BatchExec(value = "类名上的注解")
  6. public abstract class ParentClass3 {
  7.  
  8. public void abstractMethod() {
  9. System.out.println("ParentClass3");
  10. }
  11.  
  12. @BatchExec(value = "父类中新增的doExtends方法")
  13. public void doExtends() {
  14. System.out.println(" ParentClass doExtends ...");
  15. }
  16. }

该继承类的注解可见测试:

  1. package com.dxz.annotation.demo3;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import com.dxz.annotation.BatchExec;
  6.  
  7. public class MainTest3 {
  8. public static void main(String[] args) throws SecurityException, NoSuchMethodException {
  9.  
  10. Class<ParentClass3> clazz = ParentClass3.class;
  11.  
  12. if (clazz.isAnnotationPresent(BatchExec.class)) {
  13. BatchExec cla = clazz.getAnnotation(BatchExec.class);
  14. System.out.println("类:子类可继承,注解读取='" + cla.value()+"'");
  15. } else {
  16. System.out.println("类:子类不能继承到接口类上Annotation");
  17. }
  18.  
  19. // 实现抽象方法测试
  20. Method method = clazz.getMethod("abstractMethod", new Class[] {});
  21. if (method.isAnnotationPresent(BatchExec.class)) {
  22. BatchExec ma = method.getAnnotation(BatchExec.class);
  23. System.out.println("子类实现抽象方法:子类可继承,注解读取='" + ma.value()+"'");
  24. } else {
  25. System.out.println("子类实现抽象方法:没有继承到接口抽象方法中的Annotation");
  26. }
  27.  
  28. //子类中新增方法
  29. Method methodOverride = clazz.getMethod("doExtends", new Class[] {});
  30. if (methodOverride.isAnnotationPresent(BatchExec.class)) {
  31. BatchExec ma = methodOverride.getAnnotation(BatchExec.class);
  32. System.out.println("子类中新增方法:注解读取='" + ma.value()+"'");
  33. } else {
  34. System.out.println("子类中新增方法:不能读取注解");
  35. }
  36.  
  37. }
  38. }

结果:

  1. 类:子类不能继承到接口类上Annotation--场景12
  2. 子类实现抽象方法:没有继承到接口抽象方法中的Annotation--场景14
  3. 子类中新增方法:注解读取='父类中新增的doExtends方法'--场景16

子类的子类注解继承情况:

  1. package com.dxz.annotation.demo3;
  2.  
  3. public class SubClass3 extends ParentClass3 {
  4.  
  5. // 子类实现父类的抽象方法
  6. @Override
  7. public void abstractMethod() {
  8. System.out.println("子类实现父类的abstractMethod抽象方法");
  9. }
  10.  
  11. // 子类覆盖父类的doExtends方法
  12. }

测试类:

  1. package com.dxz.annotation.demo3;
  2.  
  3. import java.lang.reflect.Method;
  4.  
  5. import com.dxz.annotation.BatchExec;
  6.  
  7. public class MainTest33 {
  8. public static void main(String[] args) throws SecurityException, NoSuchMethodException {
  9.  
  10. Class<SubClass3> clazz = SubClass3.class;
  11.  
  12. if (clazz.isAnnotationPresent(BatchExec.class)) {
  13. BatchExec cla = clazz.getAnnotation(BatchExec.class);
  14. System.out.println("类:子类可继承,注解读取='" + cla.value()+"'");
  15. } else {
  16. System.out.println("类:子类不能继承到父类类上Annotation");
  17. }
  18.  
  19. // 实现抽象方法测试
  20. Method method = clazz.getMethod("abstractMethod", new Class[] {});
  21. if (method.isAnnotationPresent(BatchExec.class)) {
  22. BatchExec ma = method.getAnnotation(BatchExec.class);
  23. System.out.println("子类实现抽象方法:子类可继承,注解读取='" + ma.value()+"'");
  24. } else {
  25. System.out.println("子类实现抽象方法:没有继承到父类抽象方法中的Annotation");
  26. }
  27.  
  28. //子类未重写的方法
  29. Method methodOverride = clazz.getMethod("doExtends", new Class[] {});
  30. if (methodOverride.isAnnotationPresent(BatchExec.class)) {
  31. BatchExec ma = methodOverride.getAnnotation(BatchExec.class);
  32. System.out.println("子类未实现方法:子类可继承,注解读取='" + ma.value()+"'");
  33. } else {
  34. System.out.println("子类未实现方法:没有继承到父类doExtends方法中的Annotation");
  35. }
  36.  
  37. }
  38. }

结果:

  1. 类:子类不能继承到父类类上Annotation
  2. 子类实现抽象方法:没有继承到父类抽象方法中的Annotation--场景14
  3. 子类未实现方法:子类可继承,注解读取='父类中新增的doExtends方法'--场景18

附注

-----------------------------------------------------------------

Spring 实现事务的注解@Transactional 是可以被继承的,

通过查看它的源码可以看到@Inherited。

Annotation之二:@Inherited注解继承情况的更多相关文章

  1. Servlet 3.0 规范(二)注解驱动和异步请求

    Servlet 3.0 规范(二)注解驱动和异步请求 在 Servlet 3.0 时支持注解启动,不再需要 web.xml 配制文件. 一.Servlet 3.0 组件 Servlet 容器的组件大致 ...

  2. Spring 注解(二)注解工具类 AnnotationUtils 和 AnnotatedElementUtils

    Spring 注解(二)注解工具类 AnnotationUtils 和 AnnotatedElementUtils Spring 系列目录(https://www.cnblogs.com/binary ...

  3. spring boot: @Retention注解 @Documented 注解 @Inherited 注解

    http://www.jb51.net/article/55371.htm Retention注解 Retention(保留)注解说明,这种类型的注解会被保留到那个阶段. 有三个值:1.Retenti ...

  4. Spring 注解(二)注解工具类

    本文转载自Spring 注解(二)注解工具类 导语 首先回顾一下 AnnotationUtils 和 AnnotatedElementUtils 这两个注解工具类的用法: @Test @GetMapp ...

  5. 深入理解OOP(二):多态和继承(继承)

    本文是深入浅出OOP第二篇,主要说说继承的话题. 深入理解OOP(一):多态和继承(初期绑定和编译时多态) 深入理解OOP(二):多态和继承(继承) 深入理解OOP(三):多态和继承(动态绑定和运行时 ...

  6. 深入理解Java的注解(Annotation):自定义注解入门(2)

    要深入学习注解,我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前,我们就必须要了解Java为我们提供的元注解和相关定义注解的语法. 元注解: 元注解的作用就是负责注解其他注解.Java5. ...

  7. 深入理解Java:注解(Annotation)自己定义注解入门

    深入理解Java:注解(Annotation)自己定义注解入门 要深入学习注解.我们就必须能定义自己的注解,并使用注解,在定义自己的注解之前.我们就必须要了解Java为我们提供的元注解和相关定义注解的 ...

  8. C++ Primer 学习笔记_69_面向对象编程 --继承情况下的类作用域

    面向对象编程 --继承情况下的类作用域 引言: 在继承情况下,派生类的作用域嵌套在基类作用域中:假设不能在派生类作用域中确定名字,就在外围基类作用域中查找该名字的定义. 正是这样的类作用域的层次嵌套使 ...

  9. Annotation之三:自定义注解示例,利用反射进行解析

    @Retention定义了该Annotation被保留的时间长短有3中RetentionPolicy.SOURCE源文件有效,RetentionPolicy.CLASS:在class文件中有效,Ret ...

随机推荐

  1. javascript onclick 函数不执行

    今天被这个问题搞伤了. 原本是要给table中的元素添加onclick事件处理函数,刚开始还可以,后来就不行了,百试不得其解,反复检查,程序也没问题,耗了一个多小时,偏偏我就不信电脑会扯拐,就要看看还 ...

  2. JavaScript tips —— target与currentTarget的区别

    定义 以下是红宝书的描述 属性/方法 类型 读/写 说明 currentTarget Element 只读 其事件处理程序当前正在处理事件的那个元素 target Element 只读 事件的目标 M ...

  3. django中Model表的反向查询

    很多时候需要在多张表之间进行跨表查询,这其中外键是必须存在的,而通过外键所处的表的对象进行跨表查询, 称为正向查询.反之,则是反向查询. 正向查询很简单,这里不谈. 主要谈下反向查询. class U ...

  4. Mac OS X下实现结束占用某特定端口的进程

    ---恢复内容开始--- 1.打开终端,使用如下命令: lsof -i:**** 以上命令中,****代表端口号,我们首先要知道哪个(或哪些)进程占用该端口,比如你可以运行 lsof -i:8000, ...

  5. Ceph Monitor基础架构与模块详解

    转自:https://www.ustack.com/blog/ceph-monitor/ Ceph rados cluster离不开Monitor,如果没有Monitor,则Ceph将无法执行一条简单 ...

  6. DOCKER实战案例

    操作系统:[root@yz6205 ~]# docker search busyboxNAME DESCRIPTION STARS OFFICIAL AUTOMATEDbusybox Busybox ...

  7. JSON.stringify的三个参数

    前段时间勾股有提到stringify是支持三个参数,刷新的了我的认知,后来查到文档才发现还真的是支持三个参数的. 参考资料: stringify stringify方法顾名思义,就是把JSON序列换, ...

  8. .Net 中的IL中间语言基本语法

    一.前言 IL是什么? Intermediate Language (IL)微软中间语言 C#代码编译过程? C#源代码通过LC转为IL代码,IL主要包含一些元数据和中间语言指令: JIT编译器把IL ...

  9. R语言-数据类型与运算符

    一.在线安装包 install.packages(package_name) 二.查看变量 ls() 三.删除变量 rm() 四.变量类型 元数据类型:字符,整形,数字,虚数,BOOL 向量:vec= ...

  10. JS同源策略和跨域访问

    同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之上的,浏览器只 ...