聊聊编译时注解(一)

题图

动手写 demo !

先来看一些用到的注解:
系统自带的
MainActivity

ButterKnife
ButterKnife

以上是两种比较常见的注解。大家肯定也遇到过,今天要讲的是编译时的注解,先把基本概念搬出来晒一下:

APT
APT (Annotation Processing Tool) 是一种处理注释的工具,它对源代码文件进行检测找出其中的 Annotation,使用 Annotation 进行额外的处理。
Annotation 处理器在处理 Annotation 时可以根据源文件中的 Annotation 生成额外的源文件和其它的文件(文件具体内容由 Annotation 处理器的编写者决定), APT 还会编译生成的源文件和原来的源文件,将它们一起生成 class 文件。

在 JDK 1.5 之后,Java 语言提供了对注解(Annotation)的支持,这些注解和普通的 Java 代码一样,是在运行期间发挥作用的。在JDK 1.6 中实现了JSR-269 规范。提供了一组差入职注解处理器的标准 API 在编译期间对注解进行处理,我们可以把它看做是一组编译器的插件,在这些插件里面,可以读取,修改,添加抽象语法书中的任意元素。

三类注解:

  • 标准 Annotation
    包括 Override, Deprecated, SuppressWarnings,是java自带的几个注解,他们由编译器来识别,不会进行编译。
  • 元 Annotation
    @Retention, @Target, @Inherited, @Documented,它们是用来定义 Annotation 的 Annotation。也就是当我们要自定义注解时,需要使用它们。
  • 自定义 Annotation
    根据需要,自定义的Annotation。

###自定义 Annotation:

@Retention: 定义注解的保留策略

  • @Retention(RetentionPolicy.SOURCE)
    SOURCE
    该注解仅用于源码阶段,就是我们编写的java文件。
  • @Retention(RetentionPolicy.CLASS)
    CLASS
    该注解用于源码、类文件阶段。就是我们编写java文件和编译后产生的class文件。
  • @Retention(RetentionPolicy.RUNTIME)
    RUNTIME
    该注解用于源码、类文件和运行时阶段。

@Target:定义注解的作用目标

  • @Target(ElementType.TYPE)
    接口、类、枚举、注解
  • @Target(ElementType.FIELD)
    字段、枚举的常量
  • @Target(ElementType.METHOD)
    方法
  • @Target(ElementType.PARAMETER)
    方法参数
  • @Target(ElementType.CONSTRUCTOR)
    构造函数
  • @Target(ElementType.LOCAL_VARIABLE)
    局部变量
  • @Target(ElementType.ANNOTATION_TYPE)
    注解
  • @Target(ElementType.PACKAGE)

@interface 表示申明注解用的

写完了注解的知识,接下来我们写个 demo 简单跑一下,加深下理解。

先来看段代码
MainActivity

这段代码中我们看到使用了「@ClickAnnotation」这句代码。那为什么加了这句就会起作用呢?这就是前面讲到的使用了「@Target(ElementType.METHOD)」,作用目标就是在 method 上。后面包含了两个值,一个是 int 型的资源 id ,一个是 String 型。

看看这段代码运行结果
运行结果

那么,上面添加的注解到底做了什么事情呢?我们看下 generated 中生成的代码,可以看到多了一个 MAinActivity$$PROXY 的文件。

生成的文件目录

先不关心这个文件是怎么来的,先打开看看里面是什么东西,打开后可以看到具体生成的代码:
生成的代码

看到这里,大家应该大致上能够了解为什么简单加了注解后会出现上面 gif 显示的效果。其实真正起作用的是这份 java 代码。而这份代码在编译的时候就已经生成了,所以 app 运行的时候就显示了 toast。

今天先写到这,下次聊聊这份 java 代码具体是怎么生成的。

Demo 源码这这边。大家可以先动手玩一下。这样有助于加深理解。
Demo 源码:https://github.com/ibrothergang/DemoAnnotation