【中软国际】HarmonyOS 注解的使用 原创 精华
深开鸿开发板
发布于 2021-8-19 13:09
浏览
1收藏
概述
主要作用:简化代码,提高开发效率。
通过自定义的注解使我们能够在源码阶段、编译阶段、运行阶段对代码进行操控。减轻编写”样板”代码的负担,使代码干净易读。
元注解
在自定义注解的时候,需要使用到元注解来定义我们的注解
元注解 | 说明 | 值(枚举) | 值说明 |
---|---|---|---|
@Target | 注解用在什么地方 | 1、ElementType.TYPE | 1、接口、类、枚举 |
2、ElementType.FIELD | 2、字段、枚举常量 | ||
3、ElementType.METHOD | 3、方法 | ||
4、ElementType.PARAMETER | 4、方法参数 | ||
5、ElementType.CONSTRUCTOR | 5、构造函数 | ||
6、ElementType.LOCAL_VARIABLE | 6、局部变量 | ||
7、ElementType.ANNOTATION_TYPE | 7、注解 | ||
8、ElementType.PACKAGE | 8、包 | ||
@Retention | 注解在哪个阶段有效 | 1、RetentionPolicy.SOURCE | 1、源码阶段 |
2、RetentionPolicy.CLASS | 2、编译阶段 | ||
3、RetentionPolicy.RUNTIME | 3、运行阶段 |
自定义注解
1、声明注解
功能:检测类中是否有规范的get方法
新建java libray的module,命名为annotation,创建注解类。
@Target({ElementType.TYPE})//用于 接口、类、枚举
@Retention(RetentionPolicy.CLASS)//编译阶段
public @interface CheckGetter {
}
2、编写注解处理器
新建java libray的module,命名为annotation_processor
在build.gradle中添加依赖
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//添加本地依赖
implementation project(':annotation')
}
注解处理器所做的工作,就是在代码编译的过程中,找到我们指定的注解,加上功能逻辑做出相应的处理,或者生成java文件
继承AbstractProcessor,重写对应的方法
package com.example.processor;
import com.example.annotation.CheckGetter;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;
import javax.tools.Diagnostic;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 注解处理器
* 检查是否有get方法
*/
public class CheckGetterProcessor extends AbstractProcessor {
/**
* 初始化
*/
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
}
/**
* 返回支持的源码版本
*/
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
/**
* 支持的注解类型
* 如果集合为空,不执行process方法
*/
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> annotationTypes = new HashSet<>();
annotationTypes.add(CheckGetter.class.getCanonicalName());
return annotationTypes;
}
/**
* 解析方法
*/
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
//获取自定义注解使用到的类集合
Set<TypeElement> typeElementSet = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(CheckGetter.class));
//遍历类
for (TypeElement annotatedClass : typeElementSet) {
//获取类中的属性集合
List<VariableElement> variableElementList = ElementFilter.fieldsIn(annotatedClass.getEnclosedElements());
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "属性列表:" + variableElementList);
//遍历属性
for (VariableElement field : variableElementList) {
//根据get方法规则,判断是否包含get方法
if (!containsGetter(annotatedClass, field.getSimpleName().toString())) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR,
String.format("缺少get方法! 类名:%s \t参数名:%s", annotatedClass.getQualifiedName(), field.getSimpleName()));
}
}
}
return false;
}
/**
* 根据get方法规则,判断是否包含get方法
*
* @param typeElement 类
* @param variableName 属性名
* @return 是否包含get方法
*/
private boolean containsGetter(TypeElement typeElement, String variableName) {
// get方法命名规则:getName
String getter = "get" + variableName.substring(0, 1).toUpperCase() + variableName.substring(1).toLowerCase();
//获取类中的所有方法
List<ExecutableElement> methodElementList = ElementFilter.methodsIn(typeElement.getEnclosedElements());
processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, "方法列表:" + methodElementList);
//遍历方法
for (ExecutableElement methodElement : methodElementList) {
//方法规则:非静态、命名规则、无参数
if (!methodElement.getModifiers().contains(Modifier.STATIC) &&
methodElement.getSimpleName().toString().equals(getter) &&
methodElement.getParameters().isEmpty()) {
return true;
}
}
return false;
}
}
3、注册注解处理器
1、需要在 annotation_processor模块的 main 目录下新建 resources 资源文件夹;
2、在 resources文件夹下建立 META-INF/services 目录文件夹;
3、在 META-INF/services 目录文件夹下创建 javax.annotation.processing.Processor 文件;
4、在 javax.annotation.processing.Processor 文件写入注解处理器的全称,包括包路径
4、使用注解
在entry模块的build.gradle文件中添加依赖
dependencies {
......
implementation project(':annotation')
annotationProcessor project(':annotation_processor')
}
新建Person类,使用注解,属性age不生成get方法
import com.example.annotation.CheckGetter;
@CheckGetter
public class Person {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
运行项目报错:
缺少get方法! 类名:com.example.annotation.demo.Person 参数名:age
作者:梁青松
更多原创内容请关注:中软国际 HarmonyOS 技术学院
入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2021-8-19 15:16:55修改
赞
3
收藏 1
回复
相关推荐
好的注解是优秀代码必不可少的部分!