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

点击上方“JavaEdge”,关注公众号

设为“星标”,好文章不错过!

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

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

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

35d31db0866ec12935db418353a2222f.png

1 show me code

a6f0ee91350c9382d83da00d6fc81245.png

自定义注解

6d73121ef1768195852247e2669e6bcf.png

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

5492290bf4ddc26745834a1a29abf89d.png

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

e5f7ade6005b88f229e8b689d646e332.png

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

e4ee9d5282013a70064bcd79af00514e.png

日志输出

31b2e1b5ae9680f238d59ae33d9ca6be.png

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

35d31db0866ec12935db418353a2222f.png

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

a6f0ee91350c9382d83da00d6fc81245.png

10d0f9ab98720e4c1d03036d5f62e886.png

日志输出

8c3941fa41d11f5dbd36a68c1940131b.png

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

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

35d31db0866ec12935db418353a2222f.png

3 方法上注解的继承

a6f0ee91350c9382d83da00d6fc81245.png

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

幸好Spring提供了AnnotatedElementUtils类。

3.1 AnnotatedElementUtils工具类

f8b0af84a9a0132441b13fb313252ab2.png

82da479249309b0419d0652a7732c8b2.png

对@Inherited的支持

a8da3f17c546da9072510d95c77d6323.png

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

82da479249309b0419d0652a7732c8b2.png

Find V.S Get 语义

a8da3f17c546da9072510d95c77d6323.png

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

Get 语义

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

Find 语义

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

搜索接口(如果带注释的元素是类)

搜索超类(如果带注释的元素是一个类)

解析桥接方法(如果带注释的元素是方法)

如果带注解的元素是方法,则在接口中搜索方法

如果带注解的元素是方法,则在超类中搜索方法

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

findAllMergedAnnotations

Find 对应SearchStrategy.TYPE_HIERARCHY

1adb08b670b8fba6a00b7e5eb5b90ef9.png

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

2b703de34efcdd5a8ea90627a96dc5e4.png

getAllMergedAnnotations

Get对应SearchStrategy.INHERITED_ANNOTATIONS:

7eb47e59e20e9cd2af3b3a7ccdcf3b6e.png

35d31db0866ec12935db418353a2222f.png

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

a6f0ee91350c9382d83da00d6fc81245.png

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

参考

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

c270490bda0cd4d31b85de8b93d1a740.gif

目前交流群已有800+人,旨在促进技术交流,可关注公众号添加笔者微信邀请进群

喜欢文章,点个“在看、点赞、分享”素质三连支持一下~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值