OpenHarmony开源社区
直播中

ss

6年用户 8762经验值
擅长:电源/新能源 制造/封装 RF/无线
私信 关注
[经验]

HarmonyOS注解的使用方法分享

概述
主要作用:简化代码,提高开发效率。
通过自定义的注解使我们能够在源码阶段、编译阶段、运行阶段对代码进行操控。减轻编写”样板”代码的负担,使代码干净易读。
元注解
在自定义注解的时候,需要使用到元注解来定义我们的注解

自定义注解
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 getSupportedAnnotationTypes() {
        Set annotationTypes = new HashSet<>();
        annotationTypes.add(CheckGetter.class.getCanonicalName());
        return annotationTypes;
    }
    /**
     * 解析方法
     */
    @Override
    public boolean process(Set annotations, RoundEnvironment roundEnv) {
        //获取自定义注解使用到的类集合
        Set typeElementSet = ElementFilter.typesIn(roundEnv.getElementsAnnotatedWith(CheckGetter.class));
        //遍历类
        for (TypeElement annotatedClass : typeElementSet) {
            //获取类中的属性集合
            List 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         参数名:%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 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

更多回帖

发帖
×
20
完善资料,
赚取积分