Android butterknife 的源码解析 (一) 运行时注解(与butterknife无关)

参考文章

https://juejin.im/post/5aa8bb61f265da239c7b0d55

什么是注解

首先注解主要分为三类:

类型 特点
标准 Annotation 包括 Override, Deprecated, SuppressWarnings,是java自带的几个注解,他们由编译器来识别,不会进行编译, 不影响代码运行,至于他们的含义不是这篇博客的重点,这里不再讲述。
元 Annotation @Retention, @Target, @Inherited, @Documented,它们是用来定义 Annotation 的 Annotation。也就是当我们要自定义注解时,需要使用它们。
自定义 Annotation 根据需要,自定义的Annotation。而自定义的方式

自定义注解

Retention

可选 特点
RetentionPolicy.SOURCE 源码时注解,一般用来作为编译器标记。如Override, Deprecated, SuppressWarnings。
RetentionPolicy.RUNTIME 运行时注解,在运行时通过反射去识别的注解。
RetentionPolicy.CLASS 编译时注解,在编译时被识别并处理的注解。

Target

可选 特点
ElementType.TYPE 类、接口、注解类型或枚举
ElementType.FIELD 属性
ElementType.METHOD 方法
ElementType.PARAMETER 用于描述参数
ElementType.CONSTRUCTOR 构造方法
ElementType.LOCAL_VARIABLE 局部变量
ElementType.ANNOTATION_TYPE 注解类
ElementType.PACKAGE

@interface

@interface并不是说ContentView是一个接口,而是声明注解
就像申明类用关键字class一样。申明注解用的就是@interface。
(值得注意的是:在ElementType的分类中,class、interface、Annotation、enum同属一类为Type,并且从官方注解来看,似乎interface是包含@interface的)

运行时注解

在运行时根据注解,通过反射获取具体信息,然后做一些操作。
(所以也会带来一定的性能开销)

  • 声明注解
import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface PrintView {
    int value();
}
  • 查找注解,并输出
public class Parent {
    public void create() {
        //注解解析
        PrintView annotation = this.getClass().getAnnotation(PrintView.class);
        if (annotation != null) {
            try {
                int value = annotation.value();
                System.out.println("查找到的值 -> " + value);
            } catch (RuntimeException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 使用注解
@PrintView(12345)
public class Child extends Parent {}
public class main {
    public static void main(String[] args) {
        Child child = new Child();
        child.create();
    }
}
// 输出
// 查找到的值 -> 12345

猜你喜欢

转载自blog.csdn.net/qq_30889373/article/details/80461319