当前位置: 首页 > news >正文

Java 注解使用教程

简介

Java 1.5 引入了注解,现在它在 Java EE 框架(如 HibernateJerseySpring )中被大量使用。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.CLASSjava 编译器可以访问,但 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 引入了注解&#xff0c;现在它在 Java EE 框架&#xff08;如 Hibernate、Jersey 和 Spring &#xff09;中被大量使用。Java 注释是该语言的一个强大特性&#xff0c;用于向 Java 代码中添加元数据。它们不直接影响程序逻辑&#xff0c;但可以由工具、库或框架…...

网络安全学习

博客目录 1.Ddos 攻击2.SYN Flood3.如何应对 Ddos 攻击4.Xss 漏洞5.越权访问漏洞6.水平越权与垂直越权7.水平越权8.垂直越权 1.Ddos 攻击 DDos 全名 Distributed Denial of Service&#xff0c;翻译成中文就是分布式拒绝服务。指的是处于不同位置的多个攻击者同时向一个或数个…...

4 前端前置技术(上):AJAX技术、Axios技术(前端发送请求)

文章目录 前言一、Ajax技术&#xff08;从服务端获取数据&#xff0c;发送各种请求&#xff09;0 接口文档管理&#xff1a;使用apipost等接口测试软件创建接口便于前端后端分离测试1 基本概念2 原生Ajax使用示例&#xff08;几年前的早期用法&#xff09; 二、 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的核心组件&#xff0c;MVC框架、响应缓存、身份验证、CORS、Swagger等都是内置中间件。 广义上来讲&#xff1a;Tomcat、WebLogic、Redis、IIS&#xff1b;狭义上来讲&#xff0c;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结构 模块结构 模块代码 注&#xff1a;cpp扩展请参考作者原…...

使用jmeter进行压力测试

使用jmeter进行压力测试 jmeter安装 官网安装包下载&#xff0c;选择二进制文件&#xff0c;解压。 tar -xzvf apache-jmeter-x.tgz依赖jdk安装。 yum install java-1.8.0-openjdk环境变量配置&#xff0c;修改/etc/profile文件&#xff0c;添加以下内容。 export JMETER/…...

LQB(0)-python-基础知识

一、Python开发环境与基础知识 python解释器&#xff1a;用于解释python代码 方式&#xff1a; 1.直接安装python解释器 2.安装Anaconda管理python环境 python开发环境&#xff1a;用于编写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接受不到鼠标事件

一、问题 在项目的需求中&#xff0c;地图A上面需要叠放一个任务窗口B&#xff0c;B覆盖了A&#xff0c;导致A接受不到鼠标及滚轮事件。 二、解决方案 1、Qt::WA_TransparentForMouseEvents 是 Qt 框架中的一个属性&#xff0c;用于使指定的控件及其子控件不响应鼠标事件。当启…...

Unity安装教学与相关问题

文章目录 1. 前言2.Unity Hub2.1 下载Unity Hub2.2 安装Unity Hub2.3 注册Unity账号2.4 在Hub上登录账号2.5 在Hub上获取许可证 3. 下载并安装Unity3.1 从Unity Hub下载&#xff08;推荐&#xff09;3.1.1 选择下载版本3.1.2 选择下载组件3.1.3 安装Visual Studio Community 20…...

[Python人工智能] 四十九.PyTorch入门 (4)利用基础模块构建神经网络并实现分类预测

从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解PyTorch构建回归神经网络。这篇文章将介绍如何利用PyTorch构建神经网络实现分类预测,其是使用基础模块构建。前面我们的Python人工智能主要以TensorFlow和Keras为主,而现在最主流的深度学习框…...

实现一个 LRU 风格的缓存类

实现一个缓存类 需求描述豆包解决思路&#xff1a;实现代码&#xff1a;优化11. std::list::remove 的时间复杂度问题2. 代码复用优化后的代码优化说明 优化21. 边界条件检查2. 异常处理3. 代码封装性4. 线程安全优化后的代码示例优化说明 DeepSeek&#xff08;深度思考R1&…...

【蓝桥杯嵌入式】4_key:单击+长按+双击

1、电路图 将4个按键的引脚设置为input&#xff0c;并将初始状态设置为Pull-up&#xff08;上拉输入&#xff09; 为解决按键抖动的问题&#xff0c;我们使用定时器中断进行消抖 打开TIM3时钟并设置参数&#xff0c;中断间隔10ms&#xff0c;当计数达到10000时溢出。80M/80/10…...

深入理解 C# 与.NET 框架

.NET学习资料 .NET学习资料 .NET学习资料 一、引言 在现代软件开发领域&#xff0c;C# 与.NET 框架是构建 Windows、Web、移动及云应用的强大工具。C# 作为一种面向对象的编程语言&#xff0c;而.NET 框架则是一个综合性的开发平台&#xff0c;它们紧密结合&#xff0c;为开…...

10. 神经网络(二.多层神经网络模型)

多层神经网络&#xff08;Multi-Layer Neural Network&#xff09;&#xff0c;也称为深度神经网络&#xff08;Deep Neural Network, DNN&#xff09;&#xff0c;是机器学习中一种重要的模型&#xff0c;能够通过多层次的非线性变换解决复杂的分类、回归和模式识别问题。以下…...

spark 性能调优 (一):执行计划

在 Spark 中&#xff0c;explain 函数用于提供数据框&#xff08;DataFrame&#xff09;或 SQL 查询的逻辑计划和物理执行计划的详细解释。它可以帮助开发者理解 Spark 是如何执行查询的&#xff0c;包括优化过程、转换步骤以及它将采用的物理执行策略。 1. 逻辑计划 (Logical…...

“卫星-无人机-地面”遥感数据快速使用及地物含量计算的实现方法

在与上千学员交流过程中&#xff0c;发现科研、生产和应用多源遥感数据时&#xff0c;能快速上手&#xff0c;发挥数据的时效性&#xff0c;尽快出创新性成果&#xff0c;是目前的学员最迫切的需求。特别是按照“遥感数据获取-处理-分析-计算-制图”全流程的答疑解惑&#xff0…...

杨氏数组中查找某一数值是否存在

判断数据是否存在于杨氏矩阵中 &#xff08;小米真题&#xff09; 题目&#xff1a;有一个数字矩阵&#xff0c;矩阵的每行从左到右是递增的&#xff0c;矩阵从上到下是递增的&#xff0c;请编写程序在这样的矩阵中查找某个数字是否存在。 要求&#xff1a;时间复杂度小于O(N) …...

c语言对应汇编写法(以中微单片机举例)

芯片手册资料 1. 赋值语句 C语言&#xff1a; a 5; b a; 汇编&#xff1a; ; 立即数赋值 LDIA 05H ; ACC 5 LD R01,A ; R01 ACC&#xff08;a5&#xff09;; 寄存器间赋值 LD A,R01 ; ACC R01&#xff08;读取a的值&#xff09; LD R02,A ; R02 ACC&…...

论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)

HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

嵌入式学习笔记DAY33(网络编程——TCP)

一、网络架构 C/S &#xff08;client/server 客户端/服务器&#xff09;&#xff1a;由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序&#xff0c;负责提供用户界面和交互逻辑 &#xff0c;接收用户输入&#xff0c;向服务器发送请求&#xff0c;并展示服务…...

排序算法总结(C++)

目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指&#xff1a;同样大小的样本 **&#xff08;同样大小的数据&#xff09;**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...