美文网首页
编译期注解学习五 - ElementKind,TypeKind,

编译期注解学习五 - ElementKind,TypeKind,

作者: sliencexiu | 来源:发表于2019-08-01 14:34 被阅读0次

    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
    
    image

    相关文章

      网友评论

          本文标题:编译期注解学习五 - ElementKind,TypeKind,

          本文链接:https://www.haomeiwen.com/subject/nswqdctx.html