Java 自定义注解及使用
目录
- 一、自定义注解
- 1.使用 @interface 来定义你的注解
- 2.使用 @Retention 注解来声明自定义注解的生命周期
- 3.使用 @Target 注解来声明注解的使用范围
- 4.添加注解的属性
- 二、使用自定义的注解
- 1.将注解注在其允许的使用范围
- 2.使用反射获取类成员变量上的所有注解
- 3.反射获取成员变量上的指定注解
- 4.获取方法上的指定注解
一、自定义注解
1.使用 @interface 来定义你的注解
我们定义一个类的时候是使用的 class 关键字定义的,现在我们想定义一个自己的注解 需要使用 @interface 关键字来定义。
如定义一个叫 MyAnnotation 的注解:
public @interface MyAnnotation { }
2.使用 @Retention 注解来声明自定义注解的生命周期
@Retention 用来指定注解的生命周期(源码、class文件、运行时),其可选值如下:
● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。
声明 MyAnnotation 注解的生命周期是 RetentionPolicy.RUNTIME:
import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
}
3.使用 @Target 注解来声明注解的使用范围
@Target 用来声明注解可以用在哪些地方(类上、类成员变量上、方法上、参数上等),其可选值如下:
● ElementType.CONSTRUCTOR :用于描述构造器。
● ElementType.FIELD :成员变量、对象、属性(包括enum实例)。
● ElementType.LOCAL_VARIABLE: 用于描述局部变量。
● ElementType.METHOD : 用于描述方法。
● ElementType.PACKAGE :用于描述包。
● ElementType.PARAMETER:用于描述参数。
● ElementType.ANNOTATION_TYPE:用于描述参数
● ElementType.TYPE :用于描述类、接口(包括注解类型) 或enum声明。
声明 MyAnnotation 注解可用于类成员变量和方法上:
import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD)
public @interface MyAnnotation {
}
4.添加注解的属性
为 MyAnnotation 注解添加 id 和 describe 属性:
package com.hai.tang.annotation;import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD)
public @interface MyAnnotation { int id();String describe();
}
也可以为 id 和 describe 属性添加默认值,当 id 或 describe 属性不指定具体的值的时候就会使用默认值:
package com.hai.tang.annotation;import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD)
public @interface MyAnnotation { int id() default 0;String describe() default "";
}
到这里你已经完整定义了一个叫 MyAnnotation 的注解,其声明周期是运行时,可注解在类成员变量和方法上,拥有 id 和describe 两个属性并拥有默认值。
二、使用自定义的注解
1.将注解注在其允许的使用范围
上面 MyAnnotation 注解,可注解在类成员变量和方法上。
package com.hai.tang.model;import com.alibaba.fastjson2.annotation.JSONField;
import com.hai.tang.annotation.MyAnnotation;public class Student {@JSONField(ordinal =0)@MyAnnotationpublic String name;@MyAnnotation(id=1,describe="分数")public Integer score;public Student() {}@MyAnnotation(describe="getName方法")public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getScore() {return score;}public void setScore(Integer score) {this.score = score;}
}
2.使用反射获取类成员变量上的所有注解
import com.hai.tang.annotation.MyAnnotation;
import com.hai.tang.model.Student;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;public class MainServer {public static void main(String[] args) {Class<?> studentClass = Student.class;Field[] fields = studentClass.getDeclaredFields();//获取所有的类成员变量字段for (Field field : fields) {String fieldName = field.getName(); //获取该类成员变量的名字System.out.println("成员变量名是:" + fieldName);Annotation[] annotations = field.getAnnotations(); //获取该类成员变量上所有声明周期是运行时的注解for (Annotation annotation : annotations) {Class<? extends Annotation> annotationType = annotation.annotationType();String annotationName = annotationType.getSimpleName();//注解的简短名称System.out.println(" 使用的注解是:" + annotationName);//判断该注解是不是 MyAnnotation 注解,是的话打印其 id 和 describe 属性if (annotationType.equals(MyAnnotation.class)) {MyAnnotation myAnnotation = field.getAnnotation(MyAnnotation.class);int id = myAnnotation.id();String describe = myAnnotation.describe();System.out.println(" MyAnnotation注解中的id是:" + id);System.out.println(" MyAnnotation注解中的describe是:" + describe);}}System.out.println();}}
}
输出:
成员变量是:name使用的注解是:JSONField使用的注解是:MyAnnotationMyAnnotation注解中的id是:0MyAnnotation注解中的describe是:成员变量是:score使用的注解是:MyAnnotationMyAnnotation注解中的id是:1MyAnnotation注解中的describe是:分数
3.反射获取成员变量上的指定注解
import com.hai.tang.annotation.MyAnnotation;
import com.hai.tang.model.Student;
import java.lang.reflect.Field;public class MainServer {public static void main(String[] args) {Class<?> studentClass = Student.class;//反射遍历所有成员变量Field[] fields = studentClass.getDeclaredFields();for (Field field : fields) {//如果其成员变量上有 MyAnnotation 注解,就打印成员变量名和注解里的内容if (field.isAnnotationPresent(MyAnnotation.class)) {String fieldName = field.getName();//获取变量字段上的 MyAnnotation 注解MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);int id = annotation.id();String describe = annotation.describe();System.out.println("成员变量是:" + fieldName);System.out.println("MyAnnotation注解中的id是:" + id);System.out.println("MyAnnotation注解中的describe是:" + describe);}System.out.println();}}
}
输出:
成员变量是:name
MyAnnotation注解中的id是:0
MyAnnotation注解中的describe是:成员变量是:score
MyAnnotation注解中的id是:1
MyAnnotation注解中的describe是:分数
4.获取方法上的指定注解
import com.hai.tang.annotation.MyAnnotation;
import com.hai.tang.model.Student;
import java.lang.reflect.Method;public class MainServer {public static void main(String[] args) {Class<?> studentClass = Student.class;//反射遍历所有方法Method[] methods = studentClass.getDeclaredMethods();for (Method method : methods) {//如果其方法上有 MyAnnotation 注解,就打印方法名和注解里的内容if (method.isAnnotationPresent(MyAnnotation.class)) {String methodName = method.getName();//获取方法上的 MyAnnotation 注解MyAnnotation annotation = method.getAnnotation(MyAnnotation.class);int id = annotation.id();String describe = annotation.describe();System.out.println("方法名是:" + methodName);System.out.println("MyAnnotation注解中的id是:" + id);System.out.println("MyAnnotation注解中的describe是:" + describe);}}}
}
输出:
方法名是:getName
MyAnnotation注解中的id是:0
MyAnnotation注解中的describe是:getName方法
相关文章:
Java 自定义注解及使用
目录 一、自定义注解1.使用 interface 来定义你的注解2.使用 Retention 注解来声明自定义注解的生命周期3.使用 Target 注解来声明注解的使用范围4.添加注解的属性 二、使用自定义的注解1.将注解注在其允许的使用范围2.使用反射获取类成员变量上的所有注解3.反射获取成员变量上…...
ChatGPT的强化学习部分介绍——PPO算法实战LunarLander-v2
PPO算法 近线策略优化算法(Proximal Policy Optimization Algorithms) 即属于AC框架下的算法,在采样策略梯度算法训练方法的同时,重复利用历史采样的数据进行网络参数更新,提升了策略梯度方法的学习效率。 PPO重要的突…...
JavaWeb ( 八 ) 过滤器与监听器
2.6.过滤器 Filter Filter过滤器能够对匹配的请求到达目标之前或返回响应之后增加一些处理代码 常用来做 全局转码 ,session有效性判断 2.6.1.过滤器声明 在 web.xml 中声明Filter的匹配过滤特征及对应的类路径 , 3.0版本后可以在类上使用 WebFilter 注解来声明 filter-cla…...
Notion Ai中文指令使用技巧
Notion AI 是一种智能技术,可以自动处理大量数据,并从中提取有用的信息。它能够 智能搜索:通过搜索文本和查询结果进行快速访问 自动归档:可以根据关键字和日期自动将内容归档 内容分类:可以根据内容的标签和内容的…...
Linux一学就会——编写自己的shell
编写自己的shell 进程程序替换 替换原理 用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数 以执行另一个程序。当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动 例程开始执行…...
编程练习【有效的括号】
给定一个只包括 (,),{,},[,] 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。 左括号必须以正确的顺序闭合。 每个右括号都有一个对应的相同类型的左…...
Android 音频开发——桌面小部件(七)
对于收音机的车机 APP 开发,一般都有配套的桌面小部件(Widget)开发,这里对小部件的具体实现就不介绍了,这里主要介绍一些桌面(Launcher)中的小部件(Widget)弹出窗口功能实现。 一、功能描述 在小部件上点击按钮,弹出一个有音源选择列表的弹窗,点击其他位置…...
常见的C++包管理
C包管理工具 Conan 是一款免费开源的 C/C语言的依赖项和包管理器 类似于python的anaconda Introduction — conan 2.0.4 documentationconan-io/conan: Conan - The open-source C and C package manager (github.com) CPM cmake集成的 mirrors / cpm-cmake / CPM.cmake GitC…...
基于yolov7开发构建学生课堂行为检测识别系统
yolov7也是一款非常出众的目标检测模型,在我之前的文章中也有非常详细的教程系列的文章,感兴趣的话可以自行移步阅读即可。 《基于YOLOV7的桥梁基建裂缝检测》 《YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程》 《基于YOLOv7融合…...
GPT-4 开始内测32k输入长度的版本了!你收到邀请了吗?
要说现在 GPT-4 最大的问题是什么?可能除了一时拿他没有办法的机器幻觉,就是卡死的输入长度了吧。尽管在一般的对话、搜索的场景里目前普通版本 GPT-4 的 8000 左右的上下文长度或许绰绰有余,但是在诸如内容生成、智能阅读等方面当下基础版的…...
如何用ChatGPT做新品上市推广方案策划?
该场景对应的关键词库(28个): 品牌、产品信息、新品、成分、属性、功效、人群特征、客户分析、产品定位、核心卖点、推广策略、广告、公关、线上推广、线下活动、合作伙伴、资源整合、预算、执行计划、监测、评估、微调方案、价值主张、营销策略、热点话…...
Qt之QGraphicsEffect的简单使用(含源码+注释)
文章目录 一、效果示例图1.效果演示图片3.弹窗演示图片 二.问题描述三、源码CFrame.hCFrame.cppCMainWindow.hCMainWindow.cpp 总结 一、效果示例图 1.效果演示图片 3.弹窗演示图片 二.问题描述 (因为全是简单使用,毫无技巧,直接描述问题&a…...
前端优化-css
1.css盒子模型 标准盒子模型,IE盒子模型 标准盒子模型:margin-border-padding-content IE盒子模型:margin-content(border-padding-content) 如何转换: box - sizing: border - box; // IE盒子模型 box - sizing: content - …...
第三方ipad笔哪个牌子好用?ipad触控笔推荐平价
至于选择苹果原装的电容笔,还是平替的电容笔,要看个人的需求而定,比如画图用的,可以用Apple Pencil;比如学习记笔记用的,可以用平替电容笔,目前的平替电容笔无论是品质还是性能,都非…...
windows10+detectron2完美安装教程
文章目录 前言下载detectron2安装Visual Studio 2019修改代码 前言 需要下载detectron2的github项目,安装vs2019 (强烈建议这个版本,其他的版本需要做更多地操作才能成功安装),默认其他环境没问题。 下载detectron2 链接:https…...
串口与wifi模块
经过以下学习,我们掌握: AT指令与wifi模块的测试方法:通过CH340直接测试,研究各种AT指令下wifi模块的响应信息形式。编程,使用串口中断接收wifi模块对AT指令的响应信息以及透传数据,通过判断提高指令执行的…...
上财黄烨:金融科技人才的吸引与培养
“金融科技企业在吸引人才前,应先完善人才培养机制,建立员工画像,有针对性地培训提高成员综合素质。” ——上海金融智能工程技术研究中心上海财经大学金融科技研究院秘书长&院长助理黄烨老师 01.何为数字人才? 目前大多数研…...
利用MQ事务消息实现分布式事务
MQ事务消息使用场景 消息队列中的“事务”,主要解决的是消息生产者和消息消费者的数据一致性问题。 拿我们熟悉的电商来举个例子。一般来说,用户在电商 APP 上购物时,先把商品加到购物车里,然后几件商品一起下单,最后…...
C++面向对象设计:深入理解多态与抽象类实现技巧
面向对象的多态 一、概念二、实现1. 静态多态1.1 函数重载1.2 运算符重载 2. 动态多态2.1 虚函数2.2 纯虚函数 三、虚函数1. 定义2. 实现3. 注意 四、纯虚函数1. 定义2. 作用 五、虚析构函数1. 定义2. 作用 六、 抽象类七、实现多态的注意事项1. 基类虚函数必须使用 virtual 关…...
长三角生物医药产业加速跑,飞桨螺旋桨为创新药企、医药技术伙伴装上AI大模型引擎...
生物医药是国家“十四五”规划中明确的战略性新兴产业之一。长三角地区是中国生物医药产业的排头兵,也是《“十四五”生物经济发展规划》的“生物经济先导区”之一。据《上海市生物医药产业投资指南》显示,2022 年上海市生物医药产业在 I 类国产创新药数…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
三体问题详解
从物理学角度,三体问题之所以不稳定,是因为三个天体在万有引力作用下相互作用,形成一个非线性耦合系统。我们可以从牛顿经典力学出发,列出具体的运动方程,并说明为何这个系统本质上是混沌的,无法得到一般解…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
