定义和反射Annotation类(注解)

文章目录

  • 前言
  • 一、定义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类中的成员变量、构造方法、方法都被解释了出来,解释清楚这些东西都是什么,便于其他程序员查看理解,注解的使用便利了团队之间的协作,当然注释也能起到这样的效果,只是注解可以直接在控制台中查看。


总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

vue 基于antV 实现流程图编辑器代码

最近在做流程图功能开发&#xff0c;发现阿里antV 有对应的可视化引擎&#xff0c;于是自己做了一个简单vue 基于antV 实现流程图编辑器代码 部分代码如下&#xff1a; <template><div id"flowEditorContent"><header><h3>antv X6 流程编辑…

Java热部署:让应用更新如丝般顺滑,告别繁琐重启!

目录 手动启动热部署 自动启动热部署 参与热部署监控的文件范围配置 关闭热部署 什么是热部署&#xff1f;简单说就是你程序改了&#xff0c;现在要重新启动服务器&#xff0c;嫌麻烦&#xff1f;不用重启&#xff0c;服务器会自己悄悄的把更新后的程序给重新加载一遍&…

发那科机器人IO 分配

IO 信号 也称为输入\输出信号&#xff0c;是机器人与外围设备通信的电信号

Studying-代码随想录训练营day16| 513找到左下角的值、112.路径总和、106从中序与后序遍历序列构造二叉树

第十六天&#xff0c;二叉树part03&#x1f4aa;&#x1f4aa;&#x1f4aa;&#xff0c;编程语言&#xff1a;C 目录 513找到左下角的值 112.路径总和 113.路径总和II 106从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树 总结 513找到左下角的值…

Elk安装及使用

es安装及使用 单机版安装 集群安装 132 node-01 133 node-02 135 node-03 日志用户权限有问题 看日志 解决方案&#xff1a; 出现错误后&#xff0c;再次重启前&#xff0c;需要删除三个节点/data/下的内容 9300-http 9300-tcp logstasha安装及使用 Ssh错误 Yum安装默认路…

职场记 | 有些人的成功真的不是偶然

今天跟大家聊一聊雷总的成长记&#xff0c;希望给职场中的朋友们一点启发&#xff1a; 强烈的创业精神与持续的创新意识 雷军自大学时期起就展现出了强烈的创业热情。他不仅在求学期间积极参与创业活动&#xff0c;更在毕业后迅速踏上创业道路&#xff0c;创立了多家知名企业…

大模型时代,新手和程序员如何转型入局AI行业?

在近期的全国两会上&#xff0c;“人工智能”再次被提及&#xff0c;并成为国家战略的焦点。这一举措预示着在接下来的十年到十五年里&#xff0c;人工智能将获得巨大的发展红利。技术革命正在从“互联网”向“人工智能”逐步迈进&#xff0c;我将迎来新一轮技术革新和人才需求…

NetSuite 不同类型Item的公司间交易科目的设置

我们知道&#xff0c;NetSuite中有Intercompany Preferences的设置&#xff0c;如下所示&#xff0c;分别涉及到公司间应收、公司间应付、公司间收入、公司间费用以及公司间成本共5个科目&#xff0c;非常明确清晰。 最近用户遇到的场景是&#xff0c;如果是Non-Inventory Item…

史上最全的整合Harbor安装教程,哈哈哈哈

一、安装docker 下载地址&#xff1a;https://download.docker.com/linux/static/stable/x86_64/docker-23.0.4.tgz 1.1 解压二进制包 wget https://download.docker.com/linux/static/stable/x86_64/docker-23.0.4.tgz tar zxvf docker-23.0.4.tgz mv docker/* /usr/bin1.2…

【C语言】16.动态内存管理

文章目录 1.为什么要有动态内存分配2.malloc和free2.1 malloc2.2 free 3.calloc和realloc3.1 calloc3.2 realloc 4.常见的动态内存的错误4.1 对NULL指针的解引⽤操作4.2 对动态开辟空间的越界访问4.3 对⾮动态开辟内存使⽤free释放4.4 使⽤free释放⼀块动态开辟内存的⼀部分4.5…

对红酒数据集,分别采用决策树算法和随机森林算法进行分类。

1.导入所需要的包 from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import load_wine from sklearn.model_selection import train_test_split 2.导入数据&#xff0c;并且对随机森林和决策数进…

每月 GitHub 探索|10 款引领科技趋势的开源项目

1.IT-Tools 仓库名称&#xff1a; CorentinTh/it-tools 截止发稿星数: 16842 (近一个月新增:5744) 仓库语言: Vue 仓库开源协议&#xff1a; GNU General Public License v3.0 引言 CorentinTh/it-tools 是一个开源项目&#xff0c;提供各种对开发者友好的在线工具&#xff0…

教师数字素养标准

老师们有没有想过如何让自己的课堂更加生动、互动&#xff0c;甚至超越传统的教学模式&#xff1f;是否思考过&#xff0c;数字技术如何成为我们教学的得力助手&#xff0c;让我们的课堂焕发出新的活力&#xff1f; 数字素养&#xff0c;这个听起来充满科技感的词汇&#xff0c…

接口实现多态

多态&#xff1a; 父类的引用类型变量指向了子类的对象或者是接口类型的引用类型变量指向了接口实现类 的对象。 实现关系下的多态&#xff1a; 接口 变量 new 接口实现类的对象。 接口 public abstract interface InterA {public abstract void show();}实现类 public c…

文件上传漏洞-上篇

一、概述 文件上传漏洞可以说是日常渗透测试中用得最多的一个漏洞&#xff0c;用它获得服务器权限最快最直接。在web程序中&#xff0c;经常需要用到文件上传的功能。如用户或者管理员上传图片&#xff0c;或者其它文件。如果没有限制上传类型或者限制不严格被绕过&#xff0c…

数据结构6---树

一、定义 树(Tree)是n(n>0)个结点的有限集。当n0时成为空树,在任意一棵非空树中: 1、有且仅有一个特定的称为根(Root)的结点; 2、当n>1时,其余结点可分为m(m>日)个互不相交的有限集T1、T2、...、 Tm&#xff0c;其中每一个集合本身又是一棵树&#xff0c;并且称为根的…

LabVIEW项目中的常见电机及其特点分析

在LabVIEW项目中&#xff0c;电机的选择对系统的性能和应用效果至关重要。常见电机类型包括直流电机&#xff08;DC Motor&#xff09;、步进电机&#xff08;Stepper Motor&#xff09;、交流感应电机&#xff08;AC Induction Motor&#xff09;和无刷直流电机&#xff08;BL…

【MySQL进阶之路 | 高级篇】InnoDB搜索引擎行格式

1. COMPACT行格式 COMPACT行格式是MySQL5.1的默认行格式.其结构示意图如下. 大体可以分为两部分. 记录的额外信息.这里面有包括变长字段长度列表&#xff0c;NULL值列表和记录头信息.记录的真实数据. (1).变长字段长度列表 MySQL支持一些变长的数据类型.比如VARCHAR(m), VA…

【扫雷游戏】C语言实现

机器学习&#xff1a;Transformer框架理论详解和代码实现>Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f4a5;&#x1f4a5;个人主页&#xff1a;奋斗的小羊 &#x1f4a5;&#x1f4a5;所属…

别让破损安全鞋,成为你工作中无法预见的“隐形杀手”

在日常生活中&#xff0c;安全鞋是我们的“守护神”&#xff0c;默默守护着我们的双脚&#xff0c;抵御着来自工作环境的各种风险。然而&#xff0c;当安全鞋出现破损时&#xff0c;我们却常常视而不见&#xff0c;以为这只是微不足道的小事&#xff0c;很多人可能会选择“将就…