概述

注解处理器是一个在javac中的,用来编译时扫描和处理的注解的工具。你可以为特定的注解,注册你自己的注解处理器。
注解处理器可以生成Java代码,这些生成的Java代码会组成 .java 文件,但不能修改已经存在的Java类(即不能向已有的类中添加方法)。而这些生成的Java文件,会同时与其他普通的手写Java源代码一起被javac编译。
Annotation Processor可以让我们添加自己的错误,在代码编译或者运行的时候如果代码格式不按照我们自己设置的规范的话编译将抛出我们自己设定的错误

案例

对于AbstractProcessor的API文档
我们了解了注解器后现在可以开始编写我们的注解器了,这里我就以修饰符为例子

private final String A = "123";
public String B = "123";
上面的编译器会报错
public final String C ="132";
而当如果变量同时带有public 和final的时候就不会报错

首先新建一个PublicFinal注解,这个注解的作用是判断哪些类需要用到我们自定义的错误,哪些类不用

package com.jamiexu.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author Jamiexu/Jamie793
 * @version 1.0
 * @date 2020/9/2
 * @time 9:28
 * @blog https://blog.jamiexu.cn
 **/

@Target(ElementType.TYPE) //注解类型
@Retention(RetentionPolicy.SOURCE)//注解环境
public @interface PublicFinal {
}

新建好后开始编写注解器,一样的新建一个class继承AbstractProcessor并实现他的方法开始写规则

package com.jamiexu.annotation;

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.*;
import javax.tools.Diagnostic;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author Jamiexu/Jamie793
 * @version 1.0
 * @date 2020/9/2
 * @time 9:34
 * @blog https://blog.jamiexu.cn
 **/




//Java源代码版本
@SupportedSourceVersion(SourceVersion.RELEASE_8)
//设置注解器注解的类型
@SupportedAnnotationTypes("com.jamiexu.annotation.PublicFinal")
public class PublicFinalProcessor extends AbstractProcessor {


    //记住这里必须是public否则会报错,Error:java: 服务配置文件不正确, 或构造处理程序对象javax.annotation.processing.Processor: Provider
    public PublicFinalProcessor() {
        super();
    }

//    @Override
//    public SourceVersion getSupportedSourceVersion() {
//        return SourceVersion.RELEASE_8;
//    }
//
//    @Override
//    public Set<String> getSupportedAnnotationTypes() {
//        HashSet<String> hashSet = new HashSet<>();
//        hashSet.add(PublicFinal.class.getCanonicalName());
//        return hashSet;
//    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        for(Element element:roundEnv.getElementsAnnotatedWith(PublicFinal.class)){//找到带有PublicFinal注解的类

            List<? extends Element> elementList = element.getEnclosedElements();
            for (Element e : elementList){

                //如果不是字段的话就重新循环
                if(!e.getKind().isField())
                    continue;
                //判断所有变量是否都带有了public和final修饰符
                if(!e.getModifiers().contains(Modifier.PUBLIC) || !e.getModifiers().contains(Modifier.FINAL)){

                    //如果没有修饰符就报错误
                    processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,"Field is not public and final",e);
                }
            }
        }
        return true;
    }
}

两个类都写好了后,开始注册我们的注解器如果不注册 的话我们的注解器是无法正常使用的
先在我们的工程目录新建
这样的一个文件结构
1.png
在javax.annotation.processing.Processor文件中填写我们的注解器每个注解器为一行
直接填写我们注解器完整的包名和类名即可
2.png
然后开始打包jar包,因为注解器需要打包成jar我们才能使用如果是源代码是无法使用的
1.png

2.png
3.png
4.png
5.png
6.png
7.png
8.png
9.png
10.png
11.png
12.png
13.png

在Idea中配置注解器

在实际开发中我们都会使用的一些开发工具比如说Iead,那要如何配置这个注解呢?其实也很简单也是需要打包成jar,按照上面的方法打包成jar后我们就可以开始给Idea配置了
1.png
2.png

开始编译测试

package com.jamiexu;


import com.jamiexu.annotation.PublicFinal;
import com.jamiexu.utils.android.dex.DexParser;
import com.jamiexu.utils.android.dex.throwable.DexStringParseException;


/**
 * @author Jamiexu/Jamie793
 * @version 1.0
 * @date 2020/9/1
 * @time 16:30
 * @blog https://blog.jamiexu.cn
 **/


@PublicFinal
public class Main {

    public static int post = 0x00000001;
    public static int download = 0x00000002;
    public static int get = 0x00000004;
    public static int upload = 0x00000008;


    public static void a(String a, int b, char c, boolean d, Boolean e, CharSequence f) {
    }


    public static void main(String[] args) {
        try {
            DexParser dexParser = new DexParser("c:\\users\\jamiexu\\desktop\\classes.dex");
            dexParser.parse();
        } catch (DexStringParseException e) {
            e.printStackTrace();
        }
    }


}

修仙法则

  1. 创建一个Annotation Processor继承AbstractProcessor
  2. 编写自己的规则
  3. 注册注释器
  4. 导出jar包
  5. 使用注释器

坚持看到这里的给你们几个大佬写的例子,这篇文章只是为了记录一些坑

基于注解处理器开发自动生成getter和setter方法的插件
一小时搞明白注解处理器