编译期注解学习五 - ElementKind,TypeKind,不同Element类型判断

1 ElementKind

如何判断Element的类型呢,需要用到ElementKind,ElementKind为元素的类型,元素的类型判断不需要用instanceof去判断,而应该通过getKind()去判断对应的类型
类型 说明
PACKAGE 包
ENUM 枚举
CLASS 类
ANNOTATION_TYPE 注解
INTERFACE 接口
ENUM_CONSTANT 枚举常量
FIELD 字段
PARAMETER 方法参数
LOCAL_VARIABLE 局部变量
METHOD 方法
CONSTRUCTOR 构造方法
TYPE_PARAMETER 类型参数

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

@Target({ElementType.FIELD,ElementType.TYPE,ElementType.METHOD,ElementType.PACKAGE,ElementType.PARAMETER})
@Retention(RetentionPolicy.CLASS)
public @interface ClassTarget {
    String name() default "";
    int value() default 0;
}
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;

@SupportedAnnotationTypes("com.ldx.annotationlib.ClassTarget")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class AptProcessor4 extends AbstractProcessor  {

    private Filer mFilerUtils;
    private Types mTypesUtils;
    private Elements mElementsUtils;
    private Messager mMessager;
    private Map<String,String> mOptionMap;
    private ArrayList<VariableElement> mElementList;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        mFilerUtils = processingEnv.getFiler();
        mTypesUtils = processingEnv.getTypeUtils();
        mElementsUtils = processingEnv.getElementUtils();
        mMessager = processingEnv.getMessager();
        mOptionMap = processingEnv.getOptions();
        mElementList = new ArrayList<>();
    }

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        if (set != null && set.size() > 0){

            Set<? extends Element>  elements = roundEnvironment.getElementsAnnotatedWith(ClassTarget.class);
            for (Element element : elements) {
                ElementKind kind = element.getKind();
                if (kind == ElementKind.CLASS){
                    TypeElement typeElement = (TypeElement) element;
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"=============Class======"+typeElement.getSimpleName().toString());

                }else if (kind == ElementKind.FIELD){
                    VariableElement variableElement = (VariableElement) element;
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"=============Field======"+variableElement.getSimpleName().toString());

                }else if (kind == ElementKind.METHOD){
                    ExecutableElement executableElement = (ExecutableElement) element;
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"=============Method======"+ executableElement.getSimpleName());
                }else if (kind == ElementKind.PARAMETER){
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"=============方法参数======"+ element.getSimpleName());
                } else {
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"=============othertype======"+element.getSimpleName());
                }

                ClassTarget target = element.getAnnotation(ClassTarget.class);
                mMessager.printMessage(Diagnostic.Kind.NOTE,"======name======value======="+target.name()+"   "+target.value()+"\n\n");
            }

            }
            return true;
        }
        return false;
    }

}

使用:

import com.ldx.annotationlib.BindView;
import com.ldx.annotationlib.ClassTarget;
import com.ldx.canvasdrawdemo.R;
import com.ldx.injectlib.ViewInject;

@ClassTarget(name = "class1",value = 1)
public class BindViewActivity extends AppCompatActivity {
    @ClassTarget(name = "field1",value = 2)
    @BindView(R.id.tv1)
    public TextView textView1;

    @ClassTarget(name = "field2",value = 2)
    @BindView(R.id.tv2)
    public TextView textView2;

    @ClassTarget(name = "field3",value = 2)
    @BindView(R.id.tv3)
    public TextView textView3;

    @ClassTarget(name = "method1",value = 3)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bind_view);
        ViewInject.inject(BindViewActivity.this);
        if (textView1 != null){
            System.out.println("=================="+textView1.toString());
            textView1.setText("apt 设置的Text");
        }else{
            System.out.println("==================没有绑定成功");
        }
    }

    @ClassTarget(name = "method2",value = 3)
    private void test(@ClassTarget(name = "show",value = 4) int show){

    }
}

结果:

注: =============Class======BindViewActivity
注: ======name======value=======class1   1
注: =============Field======textView1
注: ======name======value=======field1   2
注: =============Field======textView2
注: ======name======value=======field2   2
注: =============Field======textView3
注: ======name======value=======field3   2
注: =============Method======onCreate
注: ======name======value=======method1   3
注: =============Method======test
注: ======name======value=======method2   3
注: =============方法参数======show
注: ======name======value=======show   4

2 TypeKind

TypeKind为类型的属性,类型的属性判断不需要用instanceof去判断,而应该通过getKind()去判断对应的属性

类型 说明
BOOLEAN 基本类型boolean
INT 基本类型int
LONG 基本类型long
FLOAT 基本类型float
DOUBLE 基本类型double
VOID 对应于关键字void的伪类型
NULL null类型
ARRAY 数组类型
PACKAGE 对应于包元素的伪类型
EXECUTABLE 方法、构造方法、初始化
DECLARE 声明类型


package com.ldx.processor;

import com.ldx.annotationlib.ClassTarget;

import java.util.ArrayList;
import java.util.Map;
import java.util.Set;

import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.Filer;
import javax.annotation.processing.Messager;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.annotation.processing.SupportedSourceVersion;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;

@SupportedAnnotationTypes("com.ldx.annotationlib.ClassTarget")
@SupportedSourceVersion(SourceVersion.RELEASE_7)
public class AptProcessor4 extends AbstractProcessor  {

    private Filer mFilerUtils;
    private Types mTypesUtils;
    private Elements mElementsUtils;
    private Messager mMessager;
    private Map<String,String> mOptionMap;
    private ArrayList<VariableElement> mElementList;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnvironment) {
        super.init(processingEnvironment);
        mFilerUtils = processingEnv.getFiler();
        mTypesUtils = processingEnv.getTypeUtils();
        mElementsUtils = processingEnv.getElementUtils();
        mMessager = processingEnv.getMessager();
        mOptionMap = processingEnv.getOptions();
        mElementList = new ArrayList<>();
    }


  /*  如何判断Element的类型呢,需要用到ElementKind,
    ElementKind为元素的类型,元素的类型判断不需要用instanceof去判断,
    而应该通过getKind()去判断对应的类型
    类型	说明
    PACKAGE	包
    ENUM	枚举
    CLASS	类
    ANNOTATION_TYPE	注解
    INTERFACE	接口
    ENUM_CONSTANT	枚举常量
    FIELD	字段
    PARAMETER	方法参数
    LOCAL_VARIABLE	局部变量
    METHOD	方法
    CONSTRUCTOR	构造方法
    TYPE_PARAMETER	类型参数*/

    @Override
    public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
        if (set != null && set.size() > 0){

            Set<? extends Element>  elements = roundEnvironment.getElementsAnnotatedWith(ClassTarget.class);
          
            for (Element element : elements) {
               TypeMirror typeMirror =  element.asType();
               
                mMessager.printMessage(Diagnostic.Kind.NOTE,"===========typeMirror======="+typeMirror.toString());
                TypeKind typeKind = typeMirror.getKind();

                if (typeKind == TypeKind.VOID){
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"===========VOID======="+typeKind.name().toString());
                }else if (typeKind == TypeKind.EXECUTABLE){
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"===========EXECUTABLE======="+typeKind.name().toString());
                }else if (typeKind == TypeKind.DECLARED){
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"===========DECLARED======="+typeKind.name().toString());
                }else if (typeKind == TypeKind.INT){
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"===========INT======="+typeKind.name().toString());
                }else if (typeKind == TypeKind.TYPEVAR){
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"===========TYPEVAR======="+typeKind.name().toString());
                }else {
                    mMessager.printMessage(Diagnostic.Kind.NOTE,"===========else======="+typeKind.name().toString());
                }
            }
            return true;
        }
        return false;
    }

}

注解声明和使用和上面一致:
结果:

注: ===========typeMirror=======com.ldx.canvasdrawdemo.activity.BindViewActivity
注: ===========DECLARED=======DECLARED
注: ===========typeMirror=======android.widget.TextView
注: ===========DECLARED=======DECLARED
注: ===========typeMirror=======android.widget.TextView
注: ===========DECLARED=======DECLARED
注: ===========typeMirror=======android.widget.TextView
注: ===========DECLARED=======DECLARED
注: ===========typeMirror=======(android.os.Bundle)void
注: ===========EXECUTABLE=======EXECUTABLE
注: ===========typeMirror=======(int)void
注: ===========EXECUTABLE=======EXECUTABLE
注: ===========typeMirror=======int
注: ===========INT=======INT

编译期注解学习五 - ElementKind,TypeKind,不同Element类型判断_第1张图片

编译时注解学习一之 Element元素
编译时注解学习二之 注解处理器初探AbstractProcessor
编译时注解学习三之 注解处理器AbstractProcessor工具和Element属性简述
编译期注解学习四 简单的view注入框架
编译期注解学习五 - ElementKind,TypeKind,不同Element类型判断
编译期注解学习六- 生成java文件javapoet
编译期注解学习七-如何进行调试
编译时注解学习八 -模板文件读取

你可能感兴趣的:(编译期注解学习,ElementKind,TypeKind)