栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

自定义注解(一)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

自定义注解(一)

注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包,类,接口,字段,方法参数,局部变量等进行标记
分三类:
1.java自带的标准注解,如@Override(重写某个方法),@Deprecated(标明某个类或方法过时),@SuppressWarnings(标明要忽略的警告)
2.一类是元注解,元注解用于定义注解的注解,包括@Retention(标明注解被保留的阶段),@Target(标明注解使用的范围),@Inherited(标明注解可继承),@Documented(标明是否生成javadoc文档)
3.自定义注解,可以根据自己的需求定义注解

作用:
1.生成文档,通过代码里标识的元数据生成javadoc文档
2.编译检查,通过代码里标识的元数据让编译器在编译期间,进行检查验证
3.编译时动态处理,编译时通过代码里表示的元数据动态处理,例如动态生成代码
4.运行时动态处理,运行时通过代码里表示的元数据动态处理,例如使用反射注入实例

android 的自定义注解
要使用元注解来定义我们自定义的注解

元注解说明
@Target表明我们注解可以出现的地方。是一个ElementType枚举
@Retention这个注解的的存活时间
@Document表明注解可以被javadoc此类的工具文档化
@Inherited是否允许子类继承该注解,默认为false

@Target ElementType类型 说明:
ElementType.TYPE 接口、类、枚举、注解
ElementType.FIELD 字段
ElementType.METHOD 方法
ElementType.PARAMETER 方法参数
ElementType.CONSTRUCTOR 构造函数
ElementType.LOCAL_VARIABLE 局部变量
ElementType.ANNOTATION_TYPE 注解
ElementType.PACKAGE 包

@Retention RetentionPolicy类型 说明:
RetentionPolicy.SOURCE 注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃
RetentionPolicy.CLASS 注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
RetentionPolicy.RUNTIME 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在

声明注解:
通过@Retention元注解确定我们注解使用时机,如上
通过@Target确定我们注解是作用在什么上面的

自定义注解分类:
**运行时注解,**在代码运行的过程中通过反射机制找到我们自定义的注解,然后做相应的事情
**编译时注解,**在编译的过程者中用javac注解处理器来扫描到我们自定义的注解,处理注解生成我们需要的一些文件(通常是java文件)

编译时注解:
1.声明注解
2.解析注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface BindView {
    int value();
}

编译时注解的解析需要我们自己实现一个注解解析处理器。注意处理器所作的工作,就是在代码编译过程中,找到指定我们的注解,然后加上自己特定的逻辑(通常生成java文件)
注意:要实现一个module必须是java-library(因为java library才能继承处理器AbstractProcessor)
goole为了方便我们注册注解处理器,提供一个注册处理器的库@AutoService(Processor.class)的注解来进行注册

添加依赖

dependencies {
    implementation 'com.google.auto.service:auto-service:1.0-rc2'
}
@AutoService(Process.class)
public class BindViewProcessor extends AbstractProcessor {
private Elements elements;
private Messager messager;
private Filer filer;
private Types types;

    
    @Override
    public boolean process(Set set, RoundEnvironment roundEnvironment) {
	Set annotationElements = 	roundEnvironment.getElementsAnnotatedWith(BindView.class);
	for (Element element : annotationElements){
    	//获取字段名称
   	 if (element instanceof TypeElement) {
        		//注解用于类
        		try {
            	TypeElement typeElement2 = (TypeElement) element;
           	 System.out.println("typeElement2:" + typeElement2);
       	 	} catch (Exception e) {
            	e.printStackTrace();
        		}
    	} else { //注解用于字段
    		}
	}
        return false;
    }

    
    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
		elements = processingEnv.getElementUtils();
		messager = processingEnv.getMessager();
		filer = processingEnv.getFiler();
		types = processingEnv.getTypeUtils();

    }

    
    @Override
    public Set getSupportedAnnotationTypes() {
        Set sets = new HashSet<>();
        sets.add(BindView.class.getCanonicalName());
        return sets;
    }


    
    @Override
    public SourceVersion getSupportedSourceVersion() {
        return super.getSupportedSourceVersion();
    }
}

process()方法的核心是Element元素,Element代表程序的元素,在注解处理过程中,编译器会扫描所有的java源文件,并将源码中的每个部分都看作特定类型的Element
自定义处理器的过程除了要了解Element类和其它的子类,还需要4个帮助类:

注解处理器帮助类说明
Elements一个用来处理Element的工具类
Types一个用来处理TypeMirror的工具类
Filer用于创建文件(比如创建java文件)
Messager用于输出,类似print函数

这四个帮助类,可以通过在init()函数中,通过ProcessingEnvironment获取到

编写完注解处理器在app模块导入

implementation project(":模块名称")

在process函数中,通过RoundEnvironment可以返回得到使用给定注解的元素
源码:

public interface RoundEnvironment { 
    // 返回使用给定类型注解的元素。 
    Set getElementsAnnotatedWith(TypeElement var1); 
    // 返回使用给定类型注解的元素。
    Set getElementsAnnotatedWith(Class var1);
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1027661.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号