定义和反射Annotation类(注解)

news2024/10/5 17:26:55

文章目录

  • 前言
  • 一、定义Annotation类
  • 二、反射Anootation类
    • 1.元注解
    • 2.反射注解
  • 总结

前言

        在写代码的过程中,我们经常会写到注释,以此来提醒代码中的点。但是,这些注释不会被查看,也不在整个代码之中,只能在源代码中进行查看。如果想要在代码运行后获取这些注释内容,这就用到了Annotation类了,也就是注解。


一、定义Annotation类

        定义Annotation类,需要用到关键字interface,为了区分接口类型,需要在前面加上“@”符号。@interface这个关键字也隐含着继承了java.lang.Annotation接口

        定义Annotation类格式:

public @interface MyAnnotation{
    //权限修饰符 @interface 注解名称{}
}

        实操展示:

public @interface MyAnnotation{
    String value() default "";
}

         String为注解内容的类型  value()为自定义名称的注解内容参量 default为设定默认值

二、反射Annotation类

1.元注解

        元注解,即为JAVA的API库中最基础的注解。元注解为我们在自定义创建注解时,对这些自定义注解进行规范,用好这些元注解,才能使我们创建的注解发挥到应有的功能。(在用到元注解的时候,需要添加java.lang.annotation.*包

        以下是部分元注解的说明表格:

部分元注解解读
元注解功能描述
@Decumented指示某一类型的注释通过javadoc和类似默认工具进行文档化
@Inherited指示注释类型被自动继承
@Retention指示注释类型的注释要保留多久
@Taraget指示注释类型所适用的程序元素的种类
@Deprecated在java源码中被@Deprecated修饰的类、方法、变量等表示不建议使用的,可能会出现错误的,可能以后会被删除的类、方法等。标记不想使用的类,方法,变量,可以看作废案。

        在以上表格中,我们想自定义注解,那么用的最频繁的元注解为@Retention(自定义注解会不会在源代码的class文件中,还是乃至扩大到jvm的运行过程)和@Target(自定义注解是给注解、类、接口、枚举、构造方法、成员变量、枚举参数、方法、包等专门地进行注解)。

        以下是@Retention和@Target元注解的介绍,不知下面介绍如何实战,具体使用方法请看实操展示 。

@Retention元注解负责管理自定义注解的注解范围,如果想要反射注解,即获取到注解的信息,必须将@Retention设置为自定义注解在运行代码时加载到JVM中,调用RUNTIME枚举常量

        以下是@Retention元注解中的枚举类RetentionPolicy中的枚举常量:

枚举类RetentionPolicy中的枚举常量
枚举常量说明
SOURCE表示不编译Annotation到class文化中,注解有效范围最小,甚至小于注释,不能反射zhu'j'e
CLASS表示编译Annotation到class文件中,但是在运行时不加载Annotation到JVM中,会导致无法反射注解,不能获取到注解信息
RUNTIME表示在运行时加载Anntation到JVM中,有效范围最大哦,可以反射注解,获取到注解信息

         如果要反射注解,获取到注解信息,我们一定要在自定义注解类上@Retention设置为RUNTIME

使用方法:

@Retention(RentionPolicy.枚举常量);

 

@Target元注解负责管理自定义注解的注解对象, 即该自定义注解是给谁添加注解。

        以下是@Target元注解中的枚举类ElementType中的枚举常量

枚举类ElementType中的枚举常量
枚举常量说明
ANNOTATION_TYPE表示用于Annotation类型
TYPE表示用于类、接口和枚举,以及Annotation类型
CONSTRUCTOR表示用于构造方法
FIELD表示用于成员变量和枚举常量
METHOD表示用于方法
PARAMETER表示用于参数
LOCAL_VARLABLE表示用于局部变量
PACKAGE表示用于包

使用方法:

@Target(ElementType.枚举常量)

(1)以上枚举常量限制自定义注解的注解对象是谁。

(2)在代码中,注解都是放在被注解对象的上一行的。

2.反射注解

        反射注解,即在运行时获取代码注解的信息。要获取注解的信息,提供了以下方法:

反射注解的方法
方法功能描述
isAnnotationPresent(Class annotationClass)查看是否添加了指定的注解,返回布尔值
getAnnotation(Class annotationClass)获得指定的注解
getAnnotations()获得所有的注解的数组

        注意:使用以上方法反射注解的前提是,注解类标记为 @Retention(RentionPolicy.RUNTIME) 即注解加载到JVM

        实操展示:先自定义几个注解,丰富注解内容,然后创建一个Demo类。Demo类中添加构造方法,成员属性,成员变量等,这些内容都要被自定义注解进行注释。最后在main静态方法中使用上述反射注解的方法,实现获取注解信息的功能。

        自定义的成员变量注解:

import java.lang.annotation.*;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationField {
    String value() default "默认值";    //说明成员变量的含义
    boolean enable() default false;    //说明成员变量是否被废除
}

        自定义的构造方法注解:

import java.lang.annotation.*;

@Target(ElementType.CONSTRUCTOR)    //注解对象为构造方法
@Retention(RetentionPolicy.RUNTIME)    //添加至运行JVM里
public @interface AnnotationConstructors {
    String name() default "";    //解释构造方法
}

        自定义的方法注解:

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationMethod{
    String explain() default "";    //explain参数解释方法是干什么的
}

default关键字 指定参数的默认值。在无人为因素下进行注解,其值都为default默认值 

        Demo类:

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Demo3 {

    @AnnotationField(value = "姓名")
    public String name;

    @Deprecated
    @AnnotationField(value = "身份号码",enable = true)
    public int id;
    
    @AnnotationConstructors(name = "这个构造方法在解释自己")
    public Demo3(){
        System.out.println("这是一个构造方法");
    }
    
    @AnnotationMethod(explain = "这是一个加法运算函数")
    public int add(int a,int b){
        return a+b;
    }


    public static void main(String[] args) {
        Demo3 demo3 = new Demo3();
        Class c = demo3.getClass();
        Field field[] = c.getDeclaredFields();
        for(int i=0;i<field.length;i++){
            if(field[i].isAnnotationPresent(AnnotationField.class)==true){
                System.out.println("----------------------------------------------");
                AnnotationField af=field[i].getAnnotation(AnnotationField.class);
                System.out.println("成员变量:"+field[i].getName()+" 被 @AnnotationField 注解过");
                System.out.println("注解内容为:"+af.value());
                System.out.println("该成员变量是否被废除:"+af.enable());
            }
        }

        Constructor constructor;
        try {
            constructor = c.getConstructor();
            if(constructor.isAnnotationPresent(AnnotationConstructors.class)==true){
                AnnotationConstructors ac=(AnnotationConstructors)constructor.getAnnotation(AnnotationConstructors.class);
                System.out.println("----------------------------------------------");
                System.out.println("构造方法"+constructor.getName()+" 被 @AnnotationConstructor 注解过");
                System.out.println("注解内容为:"+ac.name());
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }

        try {
            Method method = c.getMethod("add",int.class,int.class);
            AnnotationMethod am = (AnnotationMethod)method.getAnnotation(AnnotationMethod.class);
            if(method.isAnnotationPresent(AnnotationMethod.class)){
                System.out.println("----------------------------------------------");
                System.out.println("方法"+method.getName()+"被 @AnnotationMethod 注解过");
                System.out.println("注解内容为:"+am.explain());
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }

    }
}

        运行结果:

         如图所示,Demo类中的成员变量、构造方法、方法都被解释了出来,解释清楚这些东西都是什么,便于其他程序员查看理解,注解的使用便利了团队之间的协作,当然注释也能起到这样的效果,只是注解可以直接在控制台中查看。


总结

        以上就是创建自定义注解,使用注解,反射注解要讲的内容,本文仅仅简单介绍了注解的使用,而注解便利了我们团队合作,促进彼此的代码可读性,标注内容避免重复“造轮子”。有补充或者更正的内容,欢迎读者在评论区中留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1847520.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mistral AI最新力作——Mistral Large媲美GPT-4

Mistral AI自豪地宣布&#xff0c;他们的最新力作——Mistral Large&#xff0c;已经正式面世。这款尖端的文本生成模型不仅在多语言理解上表现出色&#xff0c;更在推理能力上达到了顶级水平。Mistral Large能够处理包括文本理解、转换和代码生成在内的复杂多语言推理任务。 M…

依赖注入(Dependency Injection, DI)在 iOS 开发中的应用

在 iOS 开发中&#xff0c;我们经常会遇到类与类之间存在依赖关系的情况。例如&#xff0c;一个视图控制器可能需要一个服务对象来处理数据&#xff0c;这种情况下&#xff0c;视图控制器就依赖于这个服务对象。传统的做法是直接在视图控制器中创建服务对象&#xff0c;但这会导…

目标跟踪算法(bytetrack)-tensorrt部署教程

一、本机安装python环境 conda create -n bytetrace_env python=3.8 activate bytetrace_env conda install pytorch torchvision cudatoolkit=10.1 -c检测GPU是否可用,不可用不行 import torch print(torch.cuda.is_available())安装bytetrack git clone https://github.c…

车辆轨迹预测系列 (二):常见数据集介绍

车辆轨迹预测系列 (二)&#xff1a;常见数据集介绍 文章目录 车辆轨迹预测系列 (二)&#xff1a;常见数据集介绍1、NuScenes (2020)&#xff1a;1、下载2、说明 2、Waymo Open Dataset (2020)&#xff1a;1、介绍2、概述3、下载4、教程5、参考 3、Lyft Level 5 (2020)&#xff…

Ubuntu系统如何配置通过图形界面登录root用户

Ubuntu系统中的root账号默认是锁定的&#xff0c;但可以通过设置密码来启用。 需要注意的是&#xff0c;由于root用户具有对系统完全控制的权限&#xff0c;因此在使用root账户时应格外小心。一个错误的命令可能会导致系统损坏&#xff0c;这就是为什么Ubuntu默认不启用root账户…

ELK Kibana搜索框模糊搜索包含不包含

默认是KQL,点击切换Lucene搜索&#xff0c;搜索日志中包含Exception关键字&#xff0c;不包含BizException、IllegalArgumentException、DATA_SYNC_EXCEPTION关键字的日志&#xff0c;如下&#xff1a; message: *Exception AND !(message : *BizException OR message : *Ille…

五十三、openlayers官网示例Layer Spy解析——跟随鼠标透视望远镜效果、图层剪裁

官网demo地址&#xff1a; Layer Spy 这篇实现了鼠标跟随望远镜效果&#xff0c;鼠标移动时绘制一个圆形的剪裁区剪裁上层图层。 container.addEventListener("mousemove", function (event) {mousePosition map.getEventPixel(event);map.render();});container.a…

工具分享:Search_Viewer

文章目录 前言Search_Viewer介绍安装方式使用方式 前言 本文推荐工具Search_Viewer&#xff0c;详细介绍其安装和使用方式。 Search_Viewer介绍 集Fofa、Hunter鹰图、Shodan、360 quake、Zoomeye 钟馗之眼、censys 为一体的空间测绘gui图形界面化工具&#xff0c;支持一键采…

【Python】成功解决TypeError: missing 1 required positional argument

【Python】成功解决TypeError: missing 1 required positional argument 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1…

事件驱动架构详解:触发与响应构建高效系统

目录 前言1. 事件驱动架构概述1.1 什么是事件1.2 事件驱动架构的核心概念 2. 事件驱动架构的实现2.1 基于消息队列的实现2.2 基于发布-订阅模式的实现2.3 基于流处理的实现 3. 事件驱动架构的优势3.1 松耦合性3.2 可扩展性3.3 异步处理3.4 灵活性 4. 事件驱动架构的应用场景4.1…

【论文复现|智能算法改进】改进麻雀算法的无人机三维路径规划

目录 1.UAV路径规划数学模型2.改进点3.结果展示4.参考文献5.代码获取 1.UAV路径规划数学模型 【智能算法应用】蜣螂优化算法DBO求解UAV路径规划 2.改进点 Logistics混沌映射 X n 1 μ X n ( 1 − X n ) , X n ∈ ( 0 , 1 ) (1) X_{_{n1}} \mu X_{_n}( 1 - X_{_n} ) ,\qua…

CSS属性选择器具有不区分大小写的模式

今天&#xff0c;我偶然发现了 caniuse.com 项目的一期&#xff0c;其中提到了新的和即将推出的 CSS Level 4 选择器。 这个列表很长&#xff0c;并且有许多新的选择器正在开发中。一个新的选择器标志引起了我的注意&#xff1b;属性选择器将变成一个 i 标志&#xff0c;这使得…

CRMEB PRO企业微信通讯录配置

企业微信通讯录配置 登录企业微信管理后台 企业微信 1、点击【管理工具】找到【通讯录同步】点击进入 2、点击【开启API接口同步】 进入设置【通讯录同步】页面后&#xff0c;权限一栏&#xff0c;勾选【API编辑通讯录】勾选【开启手动编辑】&#xff1b; 3、点击下图箭头所…

服务端代码编写中MySql大小写在Java中报错问题解决

报错信息&#xff1a; 原因&#xff1a;MySql和Java变量大小写产生的冲突。 经过查阅各个博客等&#xff0c;得出浅显结论&#xff08;不一定对&#xff09;&#xff1a;MySql大小写不敏感&#xff0c;Java大小写敏感&#xff0c;当Javabean转为MySql数据库表时&#xff0c;Ja…

Linux企业 集群批量管理-秘钥认证

集群批量管理-秘钥认证 概述 管理更加轻松&#xff1a;两个节点&#xff0c;通过秘钥认证形成进行访问&#xff0c;不需要输入密码&#xff0c;单向服务要求&#xff08;应用场景&#xff09;&#xff1a; 一些服务在使用前要求我们做秘钥认证 手动写批量管理脚本名字&#x…

Swift Combine — Subject Publishers(PassthroughSubject CurrentValueSubject)

本文主要介绍一下Subject&#xff0c;Subject 本身也是一个 Publisher&#xff0c;其定义如下&#xff1a; public protocol Subject<Output, Failure> : AnyObject, Publisher {func send(_ value: Self.Output)func send(completion: Subscribers.Completion<Self.…

基于jeecgboot-vue3的Flowable流程-自定义业务表单处理(一)支持同一个业务多个关联流程的选择支持

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 这部分先讲讲支持自定义业务表单一个业务服务表单多个流程的支持处理 1、后端mapper部分 如下&#xff0c;修改selectSysCustomFormByServiceName为list对象&#xff0c;以便支持多个 &…

苹果手机短信删除了怎么恢复?有那些方法?

IPhone短信删除怎么恢复&#xff1f;现在大多数人都会使用社交软件沟通交流&#xff0c;短信的用武之地已经没以前那么多&#xff0c;但是它的重要性一点都不能忽视&#xff0c;有些重要的短信内容值得我们保留&#xff0c;如果不小心删除了这些短信内容该怎么恢复&#xff1f;…

全网首测!文生软件平台码上飞CodeFlying,效果炸裂!

前言&#xff1a; 提到AIGC&#xff0c;在大家的印象中应该就是让AI自己生成文字&#xff0c;图片等内容吧。随着今年Sora&#xff0c;Suno的爆火&#xff0c;将AIGC的应用场景又拉到了一个新的高度&#xff0c;为人们带来了更多的遐想。在未来&#xff0c;或许可以用AI来生成…

【LLM-多模态】高效多模态大型语言模型综述

一、结论写在前面 模型规模的庞大及训练和推理成本的高昂&#xff0c;限制了MLLMs在学术界和工业界的广泛应用。因此&#xff0c;研究高效轻量级的MLLMs具有巨大潜力&#xff0c;特别是在边缘计算场景中。 论文深入探讨了高效MLLM文献的领域&#xff0c;提供了一个全面的视角…