一、注解的基本使用

注解

元注解
定义

注解类也能使用其他的注解声明,在JDK1.5中提供了用来对注解类型进行注解的注解类,我们称为元注解(meta-annotation).

  • @Target:作用于哪些节点,是个数组可传多个
    • ElementType.ANNOTATION_TYPE 可以应用于注解类型。
    • ElementType.CONSTRUCTOR 可以应用于构造函数。
    • ElementType.FIELD 可以应用于字段或属性。
    • ElementType.LOCAL_VARIABLE 可以应用于局部变量。
    • ElementType.METHOD 可以应用于方法级注解。
    • ElementType.PACKAGE 可以应用于包声明。
    • ElementType.PARAMETER 可以应用于方法的参数。
    • ElementType.TYPE 可以应用于类的任何元素。
  • @Retention : 保留级别
    • RetentionPolicy.SOURCE 标记的注解仅保留在源码级别中,并被编译器忽略。(在class文件里是看不到注解的存在)。
    • RetentionPolicy.CLASS 标记的注解在编译时由编译器保留,但 Java 虚拟机(JVM)会忽略。(Android里用的是dex,class打包成dex之后,注解会被抛弃)
    • RetentionPolicy.RUNTIME 标记的注解由 JVM 保留,因此运行时环境可以使用它。

SOURCE < CLASS < RUNTIME,即CLASS包含了SOURCE,RUNTIME包含SOURCE、CLASS。 默认是class级别。

常见配合使用场景

在这里插入图片描述

注解声明
  • @interface : 声明注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface AnnotationTest {
}
元注解
  • IntDef 为例
    限制参数取值范围时可替代枚举的使用,枚举比较耗内存。
// CountryType.java
public class CountryType {
    public static final int CHINA = 1;

    public static final int AMERICA = 2;
}

// Country.java
@IntDef({CountryType.CHINA, CountryType.AMERICA}) // IntDef 为元注解,可作用于注解上。country的取值
@Target(ElementType.PARAMETER) // 此注解 在方法参数上
@Retention(RetentionPolicy.SOURCE) // 源码级别的
public @interface Country {
}

// 使用
setCountry(CountryType.CHINA);
private void setCountry(@Country int countryType){

}

此时可以看下编译后的class文件,source级别的注解,在class级别是否被保留。

protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setContentView(2131427356);
        
    this.setCountry(1);
}

private void setCountry(int countryType) { // 注解未被保留
}

APT 注解处理器

APT 全称Annotation Process Tools。编写好的Java源文
件,需要经过 javac 的编译,翻译为虚拟机能够加载解析的字节码Class文件。注解处理器是 javac 自带的一个工
具,用来在编译时期扫描处理注解信息。你可以为某些注解注册自己的注解处理器。 注册的注解处理器由 javac
调起,并将注解信息传递给注解处理器进行处理。

常见使用APT的开源框架:glide arouter butterknife …

APT结合注解的使用
  1. 创建两个java 模块。一个annotation 存放注解,一个compiler存放注解处理器。注意这里是java library
  2. 创建注解
  3. 创建注解处理器 并依赖注解模块
  4. 注册注解处理器
  5. 主模块依赖注解和注解处理器,并引用注解

详细代码如下:

  • annotation library:注解
    package com.by.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target(ElementType.TYPE) // 此注解作用在类上
    @Retention(RetentionPolicy.SOURCE) // 源码级别的
    public @interface MyClass {
    }
    
  • compiler library:注解处理器
  1. 在注解处理器模块,引用注解liabry

    implementation project(':annotation')
    
  2. 声明注解处理器

    @SupportedAnnotationTypes({"com.by.annotation.MyClass"})  // 需要处理的注解,这里也可以重写方法
    public class MyClassProcess extends AbstractProcessor {
        @Override
        public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
            Messager messager = processingEnv.getMessager();
            messager.printMessage(Diagnostic.Kind.NOTE, "走到注解处理器"); // 这里的打印 不要是error 级别的, 不然会崩溃
            return false;
        }
    }
    
  3. 注册注解处理器

    标红处的目录结构不能变,这里是注解处理器的注册路径。
    在这里插入图片描述

  • app 模块

    引用注解和注解处理器,并使用

    annotationProcessor project(':compiler')
    implementation project(':annotation')
    
    @MyClass
    public class CountryActivity extends AppCompatActivity {
    }
    

    运行结果

    The following annotation processors are not incremental: compiler.jar (project :compiler).
    Make sure all annotation processors are incremental to improve your build speed.
    警告: No SupportedSourceVersion annotation found on com.by.compiler.MyClassProcess, returning RELEASE_6.
    警告: 来自注释处理程序 'org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor' 的受支持 source 版本 'RELEASE_6' 低于 -source '8'
    注: 走到注解处理器
    注: 走到注解处理器
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值