前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >注解三问—小小的注解大大的能量

注解三问—小小的注解大大的能量

作者头像
码上积木
发布2020-11-09 15:10:37
2830
发布2020-11-09 15:10:37
举报
文章被收录于专栏:码上积木码上积木

今天来说说注解,小小的东西可藏着大大的能量,一起看看吧。

  • 注解是什么?有哪些元注解
  • 简单说下这几个元注解都是怎么用的
  • 注解可以用来做什么

注解是什么?有哪些元注解

注解,在我看来它是一种信息描述,不影响代码执行,但是可以用来配置一些代码或者功能。

常见的注解比如@Override,代表重写方法,看看它是怎么生成的:

代码语言:javascript
复制
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

可以看到Override被@interface所修饰,代表注解,同时上方还有两个注解@Target和@Retention,这种修饰注解的注解叫做元注解,很好理解吧,就是最基本的注解呗。java中一共有四个元注解:

  • @Target:表示注解对象的作用范围。
  • @Retention:表示注解保留的生命周期
  • @Inherited:表示注解类型能被类自动继承。
  • @Documented:表示含有该注解类型的元素(带有注释的)会通过javadoc或类似工具进行文档化。

具体说下这几个元注解都是怎么用的

@Target

target,表示注解对象的作用范围,比如Override注解所标示的就是ElementType.METHOD,即所作用的范围是方法范围,也就是只能在方法头上加这个注解。另外还有以下几个修饰范围参数:

  • TYPE:类、接口、枚举、注解类型。
  • FIELD:类成员(构造方法、方法、成员变量)。
  • METHOD:方法。
  • PARAMETER:参数。
  • CONSTRUCTOR:构造器。
  • LOCAL_VARIABLE:局部变量。
  • ANNOTATION_TYPE:注解。
  • PACKAGE:包声明。
  • TYPE_PARAMETER:类型参数。
  • TYPE_USE:类型使用声明。

比如ANNOTATION_TYPE就是表示该注解的作用范围就是注解,哈哈,有点绕吧,看看Target注解的代码:

代码语言:javascript
复制
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

带了一个ElementType类型的参数,也就是上面说到的作用范围参数,另外还被Target注解修饰了,传的参数就是ANNOTATION_TYPE,也就是我注解我自己,我设置我自己的作用范围是注解。大家自己绕一下。。

@Retention

表示注解保留的生命周期,或者说表示该注解所保留的时长,主要有以下几个可选参数:

  • SOURCE:仅存在Java源文件,经过编译器后便丢弃相应的注解。适用于一些检查性的操作,比如@Override。
  • CLASS:编译class文件时生效,存在Java源文件,以及经编译器后生成的Class字节码文件,但在运行时VM不再保留注释。这个也是默认的参数。适用于在编译时进行一些预处理操作,比如ButterKnife的@BindView,可以在编译时生成一些辅助的代码或者完成一些功能。
  • RUNTIME:存在源文件、编译生成的Class字节码文件,以及保留在运行时VM中,可通过反射性地读取注解。适用于一些需要运行时动态获取注解信息,类似反射获取注解等。

@Inherited

表示注解类型能被类自动继承。这里需要注意两点:

  • 。也就是说只有在类集成关系中,子类才会集成父类使用的注解中被@Inherited所修饰的那个注解。其他的接口集成关系,类实现接口关系中,都不会存在自动继承注解。
  • 自动继承。也就是说如果父类有@Inherited所修饰的那个注解,那么子类不需要去写这个注解,就会自动有了这个注解。

还是看个例子:

代码语言:javascript
复制
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface MyInheritedAnnotation {
 //注解1,有Inherited注解修饰
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface MyAnnotation {
 //注解2,没有Inherited注解修饰
}


@MyInheritedAnnotation
@MyAnnotation
public class BaseClass {
 //父类,有以上两个注解
}
 
public class ExtendClass extends BaseClass  {

 //子类会继承父类的MyInheritedAnnotation注解,
 //而不会继承MyAnnotation注解
}


@Documented

表示拥有该注解的元素可通过javadoc此类的工具进行文档化,也就是说生成JavaAPI文档的时候会被写进文档中。

注解可以用来做什么

主要有以下几个用处:

  • 降低项目的耦合度。
  • 自动完成一些规律性的代码
  • 自动生成java代码,减轻开发者的工作量。

很多开源库都会用到注解,就是为了方便我们开发,这也是开源库的初衷,所以注解基本上都是框架必选。比如ButterKnife,我们可以通过@BindView注解就完成了view的资源id绑定。其实就是框架在编译时就生成了一些类,然后通过反射或者一些工具类就可以完成id注入功能了。具体怎么做的呢?是用到了APT,APT全称Annotation Processing Tool,也就是注解处理器。感兴趣的可以期待下我下篇文章。

拜拜

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-11-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上积木 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 注解是什么?有哪些元注解
  • 具体说下这几个元注解都是怎么用的
    • @Target
      • @Retention
        • @Inherited
          • @Documented
          • 注解可以用来做什么
          • 拜拜
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档