大厂面试题典-注解可以继承吗,show me code?

举报
JavaEdge 发表于 2021/06/04 00:48:49 2021/06/04
【摘要】 注解可为Java代码提供元数据,框架也会利用注解暴露功能,比如Spring框架中的@Service、@Controller。 框架可通过类或方法等元素上标记的注解了解它们的功能或特性,并以此来启用或执行相应的功能。通过注解而非API调用来配置框架,属于声明式交互,可以简化框架配置,也可和框架解耦。 你也许认为类继承后,类的注解也可继承,子类重写父类方法后,父类方法上...

注解可为Java代码提供元数据,框架也会利用注解暴露功能,比如Spring框架中的@Service@Controller

框架可通过类或方法等元素上标记的注解了解它们的功能或特性,并以此来启用或执行相应的功能。通过注解而非API调用来配置框架,属于声明式交互,可以简化框架配置,也可和框架解耦。

你也许认为类继承后,类的注解也可继承,子类重写父类方法后,父类方法上的注解也能作用于子类,确定吗?

1 案例

  • 自定义注解

  • 定义被该注解标记的类Parent,设置value为Class字符串,foo方法也标记了@MyAnnotation注解

  • 子类Child继承Parent父类,并重写父类的foo方法,子类的foo方法和类上都没有@MyAnnotation注解。

  • 通过反射分别获取Parent和Child的类和方法的注解信息,并输出注解的value属性的值(如果注解不存在则输出空字符串):

  • 日志输出

父类的类和方法上的注解都可正确获得,但子类的类和方法却不能。即子类及子类的方法,无法自动继承父类和父类方法上的注解

2 @Inherited元注解实现注解的继承

  • 日志输出

子类可以获得父类类上的注解;子类的foo虽是重写父类方法,并且注解本身也支持继承,但还是无法获得方法上的注解。

因为@Inherited只能实现类上的注解继承。

3 方法上注解的继承

可通过反射在继承链上找到方法上的注解。但实现很繁琐,还需要考虑桥接方法。
幸好Spring提供了AnnotatedElementUtils类。

3.1 AnnotatedElementUtils工具类

@Inherited的支持

遵循get语义的方法将遵循Java的@Inherited注解的约定,除了在本地声明的批注(包括自定义组成的注解)优于继承的注解之外。相反,遵循find语义的方法将完全忽略@Inherited的存在,因为find搜索算法手动遍历类型和方法层次结构,从而隐式支持注解继承,而无需@Inherited

Find V.S Get Semantics

此类中的方法使用的搜索算法遵循find或get语义。

Get 语义

仅限于搜索存在于AnnotatedElement上的注解(即在本地声明或继承)或在AnnotatedElement上方的注解层次结构中声明的注释。

Find 语义

更加详尽,提供了获取语义以及对以下内容的支持:

  • 搜索接口(如果带注释的元素是类)
  • 搜索超类(如果带注释的元素是一个类)
  • 解析桥接方法(如果带注释的元素是方法)
  • 如果带注解的元素是方法,则在接口中搜索方法
  • 如果带注解的元素是方法,则在超类中搜索方法

如下俩方法其实也很相像,有何区别呢?

findAllMergedAnnotations

Find 对应 SearchStrategy.TYPE_HIERARCHY

findMergedAnnotation方法可找出父类和接口、父类方法和接口方法上的注解,并可以处理桥接方法,实现一键找到继承链的注解:

getAllMergedAnnotations

Get对应 SearchStrategy.INHERITED_ANNOTATIONS

4 Spring的@Service、@Controller会支持继承吗?

我们假设继承后,RequestMapping对应的在父子类都能找到,处理起来肯定会很麻烦,在加上这几个注解默认都是单例的,所以是不能继承的。其实spring 官方对此也有回应。

参考

  • https://github.com/spring-projects/spring-framework/issues/8859

文章来源: javaedge.blog.csdn.net,作者:JavaEdge.,版权归原作者所有,如需转载,请联系作者。

原文链接:javaedge.blog.csdn.net/article/details/109830695

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。