Java 注解使用教程
简介
Java 1.5 引入了注解,现在它在 Java EE 框架(如 Hibernate、Jersey 和 Spring )中被大量使用。Java 注释是该语言的一个强大特性,用于向 Java 代码中添加元数据。它们不直接影响程序逻辑,但可以由工具、库或框架处理,以执行特定的任务(例如代码生成、验证或自定义处理)。
元注解
目前有五种类型的元注解
@Documented:
指示使用此注解的元素应该由 javadoc 和类似的工具记录。该类型应该用于注解类型的声明,这些类型的注解会影响其客户端对已注解元素的使用。如果一个类型声明用 Documented 进行了注解,那么它的注解将成为被注解元素的公共API的一部分。
@Target:
表示注解类型适用的程序元素种类。一些可能的值是 TYPE、METHOD、CONSTRUCTOR、FIELD 等。如果不存在目标元注解,则注解可用于任何程序元素。
元素类型对应可以应用的位置:
-
TYPE:类、接口、枚举、记录 -
FIELD:字段、枚举常量 -
METHOD:方法 -
CONSTRUCTOR:构造器 -
LOCAL_VARIABLE:本地变量 -
ANNOTATION_TYPE:注解接口声明 -
PARAMETER:参数声明 -
PACKAGE:包声明 -
TYPE_PARAMETER:类型参数声明 -
TYPE_USE:类型的使用 -
MODULE:模块声明 -
RECORD_COMPONENT:记录组件声明
用法示例
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@interface MyAnnotation{ int value1(); String value2();
}
@Inherited:
表示自动继承注解类型。如果用户查询类声明上的注解类型,而类声明没有此类型的注解,则将自动查询该类的超类以获取注解类型。这个过程将重复进行,直到找到该类型的注解,或者到达类层次结构的顶端(Object)
@Retention:
表示注解类型的注解要保留多长时间。它采用 RetentionPolicy 枚举中的参数,其可能值为 SOURCE、CLASS 和 RUNTIME。
保留策略可用的值:
-
RetentionPolicy.SOURCE:源代码可用,在编译期间被丢弃,它在编译后的类中不可用。 -
RetentionPolicy.CLASS:java编译器可以访问,但JVM无法访问,它包含在class文件中。 -
RetentionPolicy.RUNTIME:运行时可用,可供Java编译器和JVM使用。
@Repeatable:
用于指示其注解的类型声明是可重复的。
内建的注解
@Override:
当想要重写一个 Superclass 的方法时,应该使用这个注解来通知编译器我们正在重写一个方法。因此,当父类方法被删除或更改时,编译器将显示错误消息。
@Deprecated:
当我们想让编译器知道某个方法已被弃用时,我们应该使用此注释。
@SuppressWarnings:
这只是为了告诉编译器忽略它们产生的特定警告,例如在 Java 泛型中使用原始类型。它的保留策略是 SOURCE,它会被编译器丢弃。
@FunctionalInterface:
此注释是在 Java 8 中引入的,用于表明该接口旨在成为一个功能接口。
@SafeVarargs:
程序员断言,注解方法或构造函数的主体不会对其 varargs 参数执行潜在的不安全操作。
使用元注解和内建注解示例
public class AnnotationExample {public static void main(String[] args) {}@Override@MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 1)public String toString() {return "Overriden toString method";}@Deprecated@MethodInfo(comments = "deprecated method", date = "Nov 17 2012")public static void oldMethod() {System.out.println("old method, don't use it.");}@SuppressWarnings({ "unchecked", "deprecation" })@MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 10)public static void genericsTest() throws FileNotFoundException {List l = new ArrayList();l.add("abc");oldMethod();}
}
注解的类型
- 标记注释
没有方法的注解称为标记注解,例如:@Override 和 @Deprecated 是标记注释
@interface MyAnnotation{}
- 单值注解
只有一个方法的注解称为单值注解
@interface MyAnnotation{ int value() default 0;
} // 应用注解
@MyAnnotation(value=10)
- 多值注解
具有多个方法的注释称为多值注释
@interface MyAnnotation{ int value1() default 1; String value2() default ""; String value3() default "abc";
} // 应用注解
@MyAnnotation(value1=10,value2="Arun Kumar",value3="Ghaziabad")
自定义注解示例
先定义三个注解
JsonSerializable
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface JsonSerializable {
}
JsonElement
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface JsonElement {String key() default "";
}
Init
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Init {
}
接着定义Person实体
import com.redmine.annotationexample.annotation.Init;
import com.redmine.annotationexample.annotation.JsonElement;
import com.redmine.annotationexample.annotation.JsonSerializable;@JsonSerializable
public class Person {@JsonElementprivate String firstName;@JsonElementprivate String lastName;@JsonElement(key = "personAge")private int age;private String address;@Initprivate void initNames() {this.firstName = this.firstName.substring(0, 1).toUpperCase() + this.firstName.substring(1);this.lastName = this.lastName.substring(0, 1).toUpperCase() + this.lastName.substring(1);}public Person(String firstName, String lastName, int age) {this.firstName = firstName;this.lastName = lastName;this.age = age;}
}
定义一个异常类
public class JsonSerializationException extends RuntimeException {public JsonSerializationException(String message) {super(message);}
}
编写注解处理器
import com.redmine.annotationexample.exception.JsonSerializationException;import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;public class ObjectToJsonConverter {public String convertObjectToJson(Object obj) throws JsonSerializationException {try {checkIfSerializable(obj);initializeObject(obj);return getJsonString(obj);} catch (Exception e) {throw new JsonSerializationException(e.getMessage());}}private void checkIfSerializable(Object obj) {if (Objects.isNull(obj)) {throw new JsonSerializationException("Object is null");}Class<?> clazz = obj.getClass();if (!clazz.isAnnotationPresent(JsonSerializable.class)) {throw new JsonSerializationException("The class" + clazz.getName() + " is not annotated with JsonSerializable");}}private void initializeObject(Object obj) throws Exception {Class<?> clazz = obj.getClass();for (Method method : clazz.getDeclaredMethods()) {if (method.isAnnotationPresent(Init.class)) {method.setAccessible(true);method.invoke(obj);}}}private String getJsonString(Object obj) throws Exception {Class<?> clazz = obj.getClass();Map<String, String> jsonElementsMap = new HashMap<>();for (Field field : clazz.getDeclaredFields()) {field.setAccessible(true);if (field.isAnnotationPresent(JsonElement.class)) {JsonElement annotation = field.getAnnotation(JsonElement.class);String mapKey = !Objects.equals(annotation.key(), "") ? annotation.key() : field.getName();jsonElementsMap.put(mapKey, field.get(obj).toString());}}return jsonElementsMap.entrySet().stream().map(entry -> "\"" + entry.getKey() + "\":\"" + entry.getValue() + "\"").collect(Collectors.joining(",", "{", "}"));}
}
单元测试运行试下
@SpringBootTest
class AnnotationExampleApplicationTests {@Testvoid contextLoads() {}@Testvoid givenObjectSerializedTheTrueReturned() throws JsonSerializationException {Person person = new Person("soufiane", "cheouati", 34);ObjectToJsonConverter serializer = new ObjectToJsonConverter();String jsonString = serializer.convertObjectToJson(person);Assertions.assertEquals("{\"personAge\":\"34\",\"firstName\":\"Soufiane\",\"lastName\":\"Cheouati\"}", jsonString);}
}
JDK 注解定义

相关文章:
Java 注解使用教程
简介 Java 1.5 引入了注解,现在它在 Java EE 框架(如 Hibernate、Jersey 和 Spring )中被大量使用。Java 注释是该语言的一个强大特性,用于向 Java 代码中添加元数据。它们不直接影响程序逻辑,但可以由工具、库或框架…...
网络安全学习
博客目录 1.Ddos 攻击2.SYN Flood3.如何应对 Ddos 攻击4.Xss 漏洞5.越权访问漏洞6.水平越权与垂直越权7.水平越权8.垂直越权 1.Ddos 攻击 DDos 全名 Distributed Denial of Service,翻译成中文就是分布式拒绝服务。指的是处于不同位置的多个攻击者同时向一个或数个…...
4 前端前置技术(上):AJAX技术、Axios技术(前端发送请求)
文章目录 前言一、Ajax技术(从服务端获取数据,发送各种请求)0 接口文档管理:使用apipost等接口测试软件创建接口便于前端后端分离测试1 基本概念2 原生Ajax使用示例(几年前的早期用法) 二、 Axios技术(对原…...
2022年全国职业院校技能大赛网络系统管理赛项模块A:网络构建(样题3)-网络部分解析-附详细代码
目录 附录1:拓扑图 附录2:地址规划表 1.SW1 2.SW2 3.SW3 4.SW4 5.SW5 6.SW6 7.SW7 8.R1 9.R2 10.R3 11.AC1 12.AC2 13.AP2 14.AP3 15.EG1 16.EG2 附录1:拓扑图 附录2:地址规划表 设备...
ASP.NET Core中间件的概念及基本使用
什么是中间件 中间件是ASP.NET Core的核心组件,MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。 广义上来讲:Tomcat、WebLogic、Redis、IIS;狭义上来讲,ASP.NET Core中的中间件指ASP.NET Core中的一个组件。中间件…...
每日Attention学习22——Inverted Residual RWKV
模块出处 [arXiv 25] [link] [code] RWKV-UNet: Improving UNet with Long-Range Cooperation for Effective Medical Image Segmentation 模块名称 Inverted Residual RWKV (IR-RWKV) 模块作用 用于vision的RWKV结构 模块结构 模块代码 注:cpp扩展请参考作者原…...
使用jmeter进行压力测试
使用jmeter进行压力测试 jmeter安装 官网安装包下载,选择二进制文件,解压。 tar -xzvf apache-jmeter-x.tgz依赖jdk安装。 yum install java-1.8.0-openjdk环境变量配置,修改/etc/profile文件,添加以下内容。 export JMETER/…...
LQB(0)-python-基础知识
一、Python开发环境与基础知识 python解释器:用于解释python代码 方式: 1.直接安装python解释器 2.安装Anaconda管理python环境 python开发环境:用于编写python代码 1.vscode 2.pycharm # 3.安装Anaconda后可以使用网页版的jupyter n…...
每日Attention学习18——Grouped Attention Gate
模块出处 [ICLR 25 Submission] [link] UltraLightUNet: Rethinking U-shaped Network with Multi-kernel Lightweight Convolutions for Medical Image Segmentation 模块名称 Grouped Attention Gate (GAG) 模块作用 轻量特征融合 模块结构 模块特点 特征融合前使用Group…...
QT 窗口A覆盖窗口B时,窗口B接受不到鼠标事件
一、问题 在项目的需求中,地图A上面需要叠放一个任务窗口B,B覆盖了A,导致A接受不到鼠标及滚轮事件。 二、解决方案 1、Qt::WA_TransparentForMouseEvents 是 Qt 框架中的一个属性,用于使指定的控件及其子控件不响应鼠标事件。当启…...
Unity安装教学与相关问题
文章目录 1. 前言2.Unity Hub2.1 下载Unity Hub2.2 安装Unity Hub2.3 注册Unity账号2.4 在Hub上登录账号2.5 在Hub上获取许可证 3. 下载并安装Unity3.1 从Unity Hub下载(推荐)3.1.1 选择下载版本3.1.2 选择下载组件3.1.3 安装Visual Studio Community 20…...
[Python人工智能] 四十九.PyTorch入门 (4)利用基础模块构建神经网络并实现分类预测
从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解PyTorch构建回归神经网络。这篇文章将介绍如何利用PyTorch构建神经网络实现分类预测,其是使用基础模块构建。前面我们的Python人工智能主要以TensorFlow和Keras为主,而现在最主流的深度学习框…...
实现一个 LRU 风格的缓存类
实现一个缓存类 需求描述豆包解决思路:实现代码:优化11. std::list::remove 的时间复杂度问题2. 代码复用优化后的代码优化说明 优化21. 边界条件检查2. 异常处理3. 代码封装性4. 线程安全优化后的代码示例优化说明 DeepSeek(深度思考R1&…...
【蓝桥杯嵌入式】4_key:单击+长按+双击
1、电路图 将4个按键的引脚设置为input,并将初始状态设置为Pull-up(上拉输入) 为解决按键抖动的问题,我们使用定时器中断进行消抖 打开TIM3时钟并设置参数,中断间隔10ms,当计数达到10000时溢出。80M/80/10…...
深入理解 C# 与.NET 框架
.NET学习资料 .NET学习资料 .NET学习资料 一、引言 在现代软件开发领域,C# 与.NET 框架是构建 Windows、Web、移动及云应用的强大工具。C# 作为一种面向对象的编程语言,而.NET 框架则是一个综合性的开发平台,它们紧密结合,为开…...
10. 神经网络(二.多层神经网络模型)
多层神经网络(Multi-Layer Neural Network),也称为深度神经网络(Deep Neural Network, DNN),是机器学习中一种重要的模型,能够通过多层次的非线性变换解决复杂的分类、回归和模式识别问题。以下…...
spark 性能调优 (一):执行计划
在 Spark 中,explain 函数用于提供数据框(DataFrame)或 SQL 查询的逻辑计划和物理执行计划的详细解释。它可以帮助开发者理解 Spark 是如何执行查询的,包括优化过程、转换步骤以及它将采用的物理执行策略。 1. 逻辑计划 (Logical…...
“卫星-无人机-地面”遥感数据快速使用及地物含量计算的实现方法
在与上千学员交流过程中,发现科研、生产和应用多源遥感数据时,能快速上手,发挥数据的时效性,尽快出创新性成果,是目前的学员最迫切的需求。特别是按照“遥感数据获取-处理-分析-计算-制图”全流程的答疑解惑࿰…...
杨氏数组中查找某一数值是否存在
判断数据是否存在于杨氏矩阵中 (小米真题) 题目:有一个数字矩阵,矩阵的每行从左到右是递增的,矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。 要求:时间复杂度小于O(N) …...
c语言对应汇编写法(以中微单片机举例)
芯片手册资料 1. 赋值语句 C语言: a 5; b a; 汇编: ; 立即数赋值 LDIA 05H ; ACC 5 LD R01,A ; R01 ACC(a5); 寄存器间赋值 LD A,R01 ; ACC R01(读取a的值) LD R02,A ; R02 ACC&…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
laravel8+vue3.0+element-plus搭建方法
创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
