天天看点

作为Android Coder,你了解注解吗?

前言

在日常开发中,经常使用注解,很多开源框架都提供了丰富的注解给开发者使用,如 ​

​ARouter​

​ 的 ​

​@Route(path = “/test/activity”)​

​ 、​

​butterknife​

​ 的 ​

​@BindView(R.id.user) EditText name;​

​ 等等,那你有没有自定义过注解,编写过注解处理器呢?本篇就来讲讲...

文章总览

作为Android Coder,你了解注解吗?

注解的概念

注解(Annotations),是元数据的一种形式,它不属于程序本身。对所注解代码的操作没有直接影响。

注解的多种用途:

  • 运行时处理:注解可以在运行时检查
  • 为编译器提供信息:编译器可以使用注解来检查错误
  • 编译或部署时处理:可生成代码、XML、文件等

注解的格式

@Any
class MyClass { … }      

注解以 ​

​@​

​ 开头后面跟上内容,注解允许包含元素:

@Any(id=666, value = "zby")
class MyClass { … }      

若只有一个 ​

​value​

​ 元素,则可省略;若没有元素,则可省略括号:

@Any("zby")        // 只有一个 value 元素
class MyClass { … }

@Any  // 没有元素
class MyClass { … }      

若注解有相同类型元素,则是重复注解:

@Any("Cheen")
@Any("Zby")
class MyClass { … }      

注解的声明

注解定义类似于接口的定义,在关键字 ​

​interface​

​ 前加 ​

​@​

​:

@interface Any {   // interface 前加 @
    int id();
    String value();
}      

注解类型

​int id()​

​ 和 ​

​String value()​

​ 是注解类型(annotation type),可定义可选的默认值:

@interface Any {
    int id();
    String value() default "zby";
}      

在使用注解时,若定义的注解类型没有默认值,则必须进行赋值:

@Any(id = 666) // id 必须要赋值,@Any 会提示 id 必须赋值
class MyClass { … }      

元注解

标注在自定义注解上方的为元注解(meta-annotations)

@Target({ElementType.TYPE, ElementType.METHOD}) 
@Retention(RetentionPolicy.SOURCE)   // 这里 Target Retention 是元注解
@interface Any {
    int id();
    String value() default “zby”;
}      

在 ​

​java.lang.annotation​

​ 中定义了几种元注解(@Retention、@Target是常使用的),如

@Retention 指定注解的存储方式,​

​RetentionPolicy.java​

​ 示例如下:

public enum RetentionPolicy {
    SOURCE, // 标记的注解仅保留在源码级别中,并被编译器忽略
    CLASS, // 标记的注解在编译时由编译器保留,但 JVM 会忽略
    RUNTIME // 标记的注解由 JVM 保留,运行时环境可以使用
}      

@Target 指定注解可使用的范围, ​

​ElementType.java​

​ 示例如下:

public enum ElementType {
    TYPE, // 类
    FIELD, // 字段或属性
    METHOD, // 方法
    PACKAGE, // 包
    TYPE_PARAMETER // 参数
}      

对于 ​

​TYPE_PARAMETER​

​ (类型参数) ,若把 ​

​Target​

​ 设置成 ​

​@Target({ElementType.TYPE_PARAMETER})​

​,表示可使用在泛型的类型参数上:

public class TypeParameterClass<@Any T> {
    public <@Any T> T foo(T t) {
        return null;
    }
}      

@Documented 表示使用指定的注解,将使用 Javadoc 工具记录这些元素

@Inherited 表示注解类型可以从父类继承

@Repeatable 表明标记的注解可以多次应用于同一声明或类型使用。

注解应用场景

根据 ​

​@Retention​

​ 元注解定义的存储方式,注解一般可使用在以下3种场景:

级别 技术 说明
源码 APT 在编译期能获取注解与注解声明的类和成员信息,一般用于生成额外的辅助类
字节码 字节码增强 在编译出Class后,通过修改Class数据以实现修改代码逻辑目的,对于是否需要修改的区分或者修改为不同逻辑的判断可以使用注解
运行时 反射

APT注解处理器

总结