【经验分享】Java注解实战进阶

原文地址:https://mp.weixin.qq.com/s/gdYysBB3aD_HmPyvEThFXw

Java猿的命根子!

自Java EE框架步入Spring Boot时代之后,注解简直是Java程序员的命根子啊,面向注解编程成了日常操作!

换句话的意思就是说:如果没有注解,我们啥也干不了哇(滑稽)。

图片

这岂不是很危险!

所以本文来唠一唠关于注解的相关操作,并自己动手来写一个注解感受一下原理。原理性的东西掌握了,心里自然就不慌了。


注解的基本原理

首先必须要说的是,注解它也不是什么高深的玩意儿,没必要畏惧它!

意如其名,其本来的意思就是用来做标注用:可以在字段变量方法接口等位置进行一个特殊的标记,为后续做一些诸如:代码生成数据校验资源整合等工作做铺垫。

对嘛,就做标记用的嘛!

注解一旦对代码标注完成,后续我们就可以结合Java强大的反射机制,在运行时动态地获取到注解的标注信息,从而可以执行很多其他逻辑,完成我们想要的自动化工作。

所以,反射必须要学好!


来!动手造一个注解

Spring自身提供了非常多好用的注解可以用来方便地帮我们做数据校验的工作。

比如,在没有注解加持时,我们想要校验 Student类:

public class Student {private Long id;        // 学号private String name;    // 姓名    private String mobile;  // 手机号码(11位)
}

我们只能通过手写 if判断来进行校验:

image-20240816102430152

这样非常繁琐!

但是借助于 Spring提供的注解,数据校验工作可以变得非常优雅,就像这样:

image-20240816102447880

于是很多人就表示疑问,这些注解到底如何实现功能的呢

今天本文则以上文的 @Length注解为例,自己动手实现一遍,这个学会了,其他注解实现原理也是类似。

图片

总共分三大步实现。

第一步:首先定义注解:@LengthCustom

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface LengthCustom {/*** 允许字符串长度的最大值*/int max();/*** 允许字符串长度的最小值*/int min();/*** 错误消息*/String errorMsg() default "string length illegal";}

下面做几点说明:

1、注解的定义有点像定义接口 interface,但唯一不同的是前面需要加一个 @符号

2、注解的成员变量只能使用基本类型、 String或者 enum枚举,比如 int可以,但 Integer这种包装类型就不行,需注意

3、像上面 @Target@Retention这种加在注解定义上面的注解,我们称为 “元注解”,元注解就是专门用于给注解添加注解的注解,哈哈,很拗口,简单理解,元注解就是天生就有的注解,可直接用于注解的定义上

4、 @Target(xxx) 用来说明该自定义注解可以用在什么位置,比如:

  • ElementType.FIELD:说明自定义的注解可以用于类的变量
  • ElementType.METHOD:说明自定义的注解可以用于类的方法
  • ElementType.TYPE:说明自定义的注解可以用于类本身、接口或 enum类型
  • 等等… 还有很多,如果记不住,建议现用现查

5、 @Retention(xxx) 用来说明你自定义注解的生命周期,比如:

  • @Retention(RetentionPolicy.RUNTIME):表示注解可以一直保留到运行时,因此可以通过反射获取注解信息
  • @Retention(RetentionPolicy.CLASS):表示注解被编译器编译进 class文件,但运行时会忽略
  • @Retention(RetentionPolicy.SOURCE):表示注解仅在源文件中有效,编译时就会被忽略

所以声明周期从长到短分别为:RUNTIME > CLASS > SOURCE ,一般来说,如果需要在运行时去动态获取注解的信息,还是得用RUNTIME,就像本文所用。

第二步:获取注解并对其进行验证

在运行时想获取注解所代包含的信息,该怎么办?那当然得用 Java的反射相关知识

下面写了一个验证函数 validate(),代码中会逐行用注释去解释想要达到的目的,认真看一下每一行的注释:

    public static String validate(Object object) throws IllegalAccessException {// 首先通过反射获取object对象的类有哪些字段// 对本文来说就可以获取到Student类的id、name、mobile三个字段Field[] fields = object.getClass().getDeclaredFields();// for循环逐个字段校验,看哪个字段上标了注解for (Field field : fields) {// if判断:检查该字段上有没有标注了@Length注解if (field.isAnnotationPresent(LengthCustom.class)) {// 通过反射获取到该字段上标注的@LengthCustom注解的详细信息LengthCustom lengthCustom = field.getAnnotation(LengthCustom.class);field.setAccessible(true);// 让我们在反射时能访问到私有变量// 用过反射获取字段的实际值:这里直接强转成string并获取长度int value = ((String) field.get(object)).length();// 将字段的实际值和注解上做标示的值进行比对if (value < lengthCustom.min() || value > lengthCustom.max()) {return lengthCustom.errorMsg();}}}return null;}
}

可见,学好Java的反射知识是多么的重要!

第三步:使用注解

这一步比较轻松,使用注解的过程往往都是很愉悦的

public class Student implements Serializable {private Long id;@LengthCustom(min = 2 , max= 4 , errorMsg = "名称长度不符合")private String name;private Integer age;private Integer classId;
}

写一个测试案例:

public class Validator {public static void main(String[] args) throws IllegalAccessException {Student 小王 = Student.builder().id(1L).name("小王").build();System.out.println(validate(小王));Student 小王2 = Student.builder().id(2L).name("小王小王小王小王小王小王").build();System.out.println(validate(小王2));}
}

结果:

null
名称长度不符合

怎么样,其实一点也不复杂吧,主要就是反射相关的知识!

好了,关于如何动手自定义注解的相关内容就抛砖引玉到这里吧,每天进步一点点,Peace!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PCB入门笔记—绘制一个只有两个排针的PCB全流程记录—立创EDA专业版

PCB绘制入门&#x1f680; 硕士毕业之后准备进入博士阶段&#xff0c;本科阶段做的硬件&#xff0c;硕士阶段做的算法&#xff0c;然后博士阶段又要做回硬件了&#xff0c;因此也是打算补一补PCB相关的内容和知识&#xff0c;毕竟做控制的话&#xff0c;之后这也是不能躲开的必…

CrowdTransfer:在AIoT社区中实现众包知识迁移

这篇论文的标题是《CrowdTransfer: Enabling Crowd Knowledge Transfer in AIoT Community》&#xff0c;由 Yan Liu, Bin Guo, Nuo Li, Yasan Ding, Zhouyangzi Zhang, 和 Zhiwen Yu 等作者共同撰写&#xff0c;发表在《IEEE Communications Surveys & Tutorials》上。以下…

Hive3:常用查询语句整理

一、数据准备 建库 CREATE DATABASE itheima; USE itheima;订单表 CREATE TABLE itheima.orders (orderId bigint COMMENT 订单id,orderNo string COMMENT 订单编号,shopId bigint COMMENT 门店id,userId bigint COMMENT 用户id,orderStatus tinyint COMMENT 订单状态 -3:用…

Halcon阈值处理的几种分割方法

Halcon阈值处理的几种分割方法 文章目录 Halcon阈值处理的几种分割方法1. 全局阈值2. 基于直方图的自动阈值分割方法3. 自动全局阈值分割方法4. 局部阈值分割方法5. var_threshold算子6 . char_threshold 算子7. dual_threshold算子 在场景中选择物体或特征是图像测量或识别的重…

2024-08-06升级记录:Android开发接口-获取定位卫星相关信息

Android中获取卫星信息的接口有两类&#xff1a; 一、GpsStatus 注意&#xff1a;此类在API级别24中已被弃用。 请使用GnssStatus和GnssStatus.Callback 。 这个类表示GPS引擎的当前状态。该类与 GpsStatus.Listener接口配合使用。 方法&#xff1a; 获取卫星信息&#xff…

24/8/15算法笔记 项目练习冰湖

import gym from matplotlib import pyplot as plt %matplotlib inline import os os.environ[SDL_VIDEODRIVER]dummy #设置环境变量 SDL_VIDEODRIVERdummy 是在使用基于 SDL (Simple DirectMedia Layer) 的应用程序时&#xff0c;告诉应用程序不使用任何视频驱动程序。这通常…

Transformer动画讲解-单头注意力和多头注意力

单头注意力和多头注意力 Transformer的起源&#xff1a;Google Brain 翻译团队通过论文《Attention is all you need》提出了一种全新的简单网络架构——Transformer&#xff0c;它完全基于注意力机制&#xff0c;摒弃了循环和卷积操作。 注意力机制是全部所需 正如论文标题所…

景联文科技:一文详解如何构建高质量SFT数据

在图像处理和计算机视觉领域中&#xff0c;将一张图像转化为可用于训练机器学习模型的数据是一项复杂而重要的任务。SFT&#xff08;Supervised Fine-Tuning&#xff0c;监督微调&#xff09;是一种常见的深度学习策略&#xff0c;在这一过程中发挥着核心作用。 SFT是指在一个预…

PostgreSQL-02-入门篇-查询数据

文章目录 1 简单查询SELECT 语句简介SELECT 语句语法SELECT 示例1) 使用 SELECT 语句查询一列数据的示例2) 使用 SELECT 语句查询多列数据的示例3) 使用 SELECT 语句查询表所有列数据的示例4) 使用带有表达式的 SELECT 语句的示例5) 使用带有表达式的 SELECT 语句的示例 2 列别…

【MySQL进阶之路】MySQL基础——从零认识MySQL

目录 主流数据库 什么是MySQL MySQL服务 从文件系统角度理解数据库 MySQL架构 SQL语句分类 存储引擎 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 主流数据库 数据库开发商特点适用场景SQL Server微软.NET程序员的最爱&#xff0c;适合中大型项目企业级应用&#xf…

Mapreduce_wordcount自定义单词计数

自定义的wordcount 数据处理过程 加载jar包 查看后面的pom文件 以上为需要的jar包路径&#xff0c;将其导入至idea中 Map package com.hadoop;import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; im…

电动汽车和混动汽车DC-DC转换器的创新设计与测试方法

汽车 DC-DC 转换器市场规模将达到187亿美元&#xff0c;年复合增长率为10%。 DC-DC 转换器是汽车的重要组成部分&#xff0c;它可以通过电压转换为各种车载系统供电&#xff0c;例如日益复杂的车载信息娱乐系统、使用驾驶辅助系统&#xff08;ADAS&#xff09;实现的增强安全功…

灵办AI免费ChatGPT4人工智能浏览器插件快速便捷(多功能)

灵办AI就是您所需的最佳助手&#xff01;我们为您带来了一款多功能AI工具&#xff0c;不仅能为您提供精准翻译&#xff0c;还能满足您的对话需求、智能续写、AI搜索、文档阅读、代码生成与修正等多种需求。灵办 AI&#xff0c;真正让工作和学习变得轻松高效&#xff01; 推荐使…

人工智能在网络安全威胁测试中的应用:LLMs如何改变网络威胁格局

一、引言 随着人工智能技术的快速发展&#xff0c;特别是大型语言模型&#xff08;LLMs&#xff09;的崛起&#xff0c;网络安全领域也迎来了新的变革。LLMs不仅在自然语言处理方面展现出惊人的能力&#xff0c;还在网络安全威胁测试中显示出巨大的潜力。本文旨在探讨LLMs在网…

【区块链+乡村振兴】链上云仓智慧动产监管平台 | FISCO BCOS应用案例

2021 年初 ,《中共中央国务院关于全面推进乡村振兴加快农业农村现代化的意见》将“乡村振兴”的重要性提升 到前所未有的战略高度。而随着科技与金融的深度融合&#xff0c;金融行业亦开始步入大数据、云计算、人工智能、区块 链的新技术发展。启动金融科技赋能乡村振兴示范工程…

微信小程序--24(列表渲染)

一、wx&#xff1a;for 1.作用 根据指定数组&#xff0c;循环渲染重复的组件结构 2.语法 <view wx:for"{{data中的数据}}"> 索引是&#xff1a;{{index}}, item项是&#xff1a;{{item}}</view> index:表索引item&#xff1a;表当前循环项 …

<数据集>骑行头盔识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;5026张 标注数量(xml文件个数)&#xff1a;5026 标注数量(txt文件个数)&#xff1a;5026 标注类别数&#xff1a;3 标注类别名称&#xff1a;[helmet, without_helmet, two_wheeler] 序号类别名称图片数框数1helm…

轻空间成功承建马来西亚吉隆坡多功能气膜馆

近期&#xff0c;轻空间&#xff08;江苏&#xff09;膜结构科技有限公司顺利完成了马来西亚吉隆坡多功能气膜馆的建设工作。这一项目是轻空间在海外市场的又一重大突破&#xff0c;不仅展现了公司在国际气膜结构领域的卓越技术实力&#xff0c;也进一步巩固了轻空间作为全球领…

IDEA关键词全局检索-之jar包

正常没有下载到源码的jar包&#xff0c;是无法检索到.class编译文件中内容的 repository本地仓库中&#xff0c;也是没有源码的 《检索步骤》 1、首先&#xff0c;下载源码 - 可以配置maven自动下载所有jar包的源码&#xff08;再同样配置File-NewProjectsSetup-Settingsfor…

u-picker 点击遮罩层 无法关闭的原因,尤其要注意最后一点

u-view 组件 u-picker 点击遮罩层无法关闭问题 &#xff08;说实话uview的文档写的真的一般&#xff0c;跟pc端的完全不能比啊&#xff09; 三个需要注意的点 1. 需要添加 closeOnClickOverlay 属性 <u-picker :show"show" :columns"columns" keyNam…