特殊的类之注解
注解🚙
- 注解的入门和作用以及原理
- 示例
- 注解的方法名就是属性名
- @Retention的作用
- @Target的作用
- 注解的属性设置默认值
天生我材必有用,千金散尽还复来。——唐代李白《将进酒》
在Java中,注解实际上是特殊类型的接口,当我们使用注解时,编译器会为我们自动创建一个实现该接口的类,该类的属性对应注解中定义的属性。在运行时,当我们获取注解实例时,实际上获取的是这个类的实例,该实例中保存了注解的属性值。
具体来说,当我们定义一个注解时,Java会为其生成一个对应的注解类型。这个类型在编译期已经确定了,它的属性都是在编译期确定的,不能动态添加或修改。
注解的入门和作用以及原理
注解是Java语言中的一种元数据,它提供了一种结构化的方式来添加关于代码的信息和元数据,这些信息可以用来编译、部署和运行时进行处理。注解提供了一种简单的方法来将元数据附加到代码中,并能够被编译器、开发工具和其他程序进行读取和处理。
注解有很多作用,其中最常见的作用是为Java代码提供一些额外的信息,以便在编译、部署和运行时进行处理。例如,Java标准库中提供了许多内置的注解,如@Override、@Deprecated和@FunctionalInterface等。这些注解可以让编译器进行静态检查,并在编译器发现代码错误时发出警告或错误。
此外,注解也可以用于自定义的元数据处理。通过使用自定义注解,开发人员可以为自己的代码添加元数据,然后使用反射和其他技术来处理该元数据。例如,Spring框架中使用了大量的注解,如@Service、@Autowired和@Transaction等,来对应用程序进行配置和管理。
注解的原理是在Java中使用了反射技术,可以在运行时获取类、方法和字段的元数据信息。通过使用Java反射API,程序可以访问这些注解,并对其进行解析和处理。在运行时,程序可以使用注解来改变代码的行为或配置,以满足不同的需求。
总之,注解是Java语言中的一个强大的功能,它为Java代码提供了一种简单和灵活的方式来添加元数据和配置信息。通过深入理解注解的基本概念和原理,开发人员可以更好地利用这一功能来编写更加强大和灵活的Java代码。
示例
import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {String value();
}public class MyClass {@MyAnnotation("Hello, World!")public void myMethod() {System.out.println("My Method");}public static void main(String[] args) throws Exception {MyClass obj = new MyClass();Class<?> cls = obj.getClass();MyAnnotation annotation = cls.getMethod("myMethod").getAnnotation(MyAnnotation.class);System.out.println(annotation.value()); // Output: Hello, World!}
}
在这个示例中,我们首先定义了一个自定义注解 @MyAnnotation
,它有一个属性 value
。
接着,我们在 MyClass
类中的 myMethod()
方法上使用了 @MyAnnotation
注解,其中 value
属性的值为 "Hello, World!"
。
在 main()
方法中,我们使用反射获取 myMethod()
方法上的 @MyAnnotation
注解,并输出其 value
属性的值。
通过运行上述代码,我们可以得到以下输出:
Hello, World!
这个示例演示了如何使用自定义注解,并利用反射来获取注解信息。实际应用中,我们可以使用自定义注解来添加各种元数据信息,然后在程序运行时对这些元数据进行解析和处理,从而实现更加灵活和可配置的代码逻辑。
注解的方法名就是属性名
在Java注解中,方法名就是属性名。在Java注解中,属性是通过方法定义的,注解中的每个方法对应一个属性。
例如,下面是一个定义了两个属性的注解示例:
public @interface MyAnnotation {String name();int age();
}
在这个注解中,有两个属性:name
和age
,分别对应String
类型和int
类型。
我们可以通过使用注解并传入属性值来使用它。例如,下面的代码演示了如何使用上述注解:
@MyAnnotation(name = "John Doe", age = 30)
public class MyClass {// ...
}
在这个例子中,我们在MyClass
类上使用了@MyAnnotation
注解,并传入了name
和age
属性的值。这些值会在编译时存储在注解实例中,以便在运行时访问。
在访问注解属性时,我们可以像调用Java对象的方法一样,使用属性名来访问属性的值。例如,下面的代码演示了如何访问MyClass
类上的@MyAnnotation
注解的属性:
MyAnnotation annotation = MyClass.class.getAnnotation(MyAnnotation.class);
String name = annotation.name(); // "John Doe"
int age = annotation.age(); // 30
在这个例子中,我们使用反射来获取MyClass
类上的@MyAnnotation
注解,并通过注解实例的方法访问其属性的值。
因此,可以看出Java注解中的方法名就是属性名。通过定义不同的方法名和类型,我们可以为注解定义不同类型的属性,以满足不同的需求。
@Retention的作用
@Retention(RetentionPolicy.RUNTIME)
是Java注解中的一个元注解,它用来指定注解的保留策略。
Java注解有三种保留策略:
-
RetentionPolicy.SOURCE
:注解只在源代码中保留,在编译时会被忽略。 -
RetentionPolicy.CLASS
:注解在编译时会被保留,但在运行时不可用。 -
RetentionPolicy.RUNTIME
:注解在运行时也会保留,可以通过反射机制获取注解信息。
@Retention(RetentionPolicy.RUNTIME)
表示该注解将在运行时保留,可以通过反射获取注解信息。
这个元注解通常用于自定义注解时,如果我们想要在运行时使用该注解,就必须指定该注解的保留策略为 RetentionPolicy.RUNTIME
。如果没有指定保留策略,默认为 RetentionPolicy.CLASS
。
例如,下面是一个自定义注解,并使用 @Retention(RetentionPolicy.RUNTIME)
指定了保留策略:
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {// ...
}
在这个注解中,我们使用了 @Retention(RetentionPolicy.RUNTIME)
元注解,指定了该注解的保留策略为 RetentionPolicy.RUNTIME
。
通过指定 @Retention(RetentionPolicy.RUNTIME)
元注解,我们可以在运行时使用该注解,并通过反射机制获取注解信息。例如,下面是一个示例,演示了如何使用反射获取一个类上的 @MyAnnotation
注解信息:
MyAnnotation annotation = MyClass.class.getAnnotation(MyAnnotation.class);
在这个示例中,我们使用 getAnnotation()
方法获取 MyClass
类上的 @MyAnnotation
注解信息,因为该注解的保留策略为 RetentionPolicy.RUNTIME
,所以在运行时可以通过反射获取注解信息。
因此,通过指定 @Retention(RetentionPolicy.RUNTIME)
元注解,我们可以在运行时使用注解,并通过反射机制获取注解信息,从而实现更加灵活和可配置的代码逻辑。
@Target的作用
@Target(ElementType.METHOD)
是Java注解中的一个元注解,它用来指定注解的使用目标。具体来说,它指定了注解可以用于哪些程序元素上。
Java注解可以用于多种程序元素上,例如类、方法、字段等。@Target
元注解用于指定注解可以用于哪些程序元素上,它的参数是一个枚举类型 ElementType
,表示注解可以用于哪些程序元素上。
在这个例子中,@Target(ElementType.METHOD)
意味着该注解只能用于方法上。
例如,下面是一个示例,演示了如何定义一个只能用于方法上的注解:
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 MyMethodAnnotation {// ...
}
在这个示例中,我们使用了 @Target(ElementType.METHOD)
元注解,指定了该注解只能用于方法上。这意味着我们不能将该注解用于其他程序元素上,如类、字段等。
通过指定 @Target
元注解,我们可以更加精确地控制注解的使用范围,从而避免在不合适的程序元素上使用注解,提高代码的可读性和可维护性。
总之,@Target(ElementType.METHOD)
的作用是指定注解只能用于方法上。通过使用 @Target
元注解,我们可以更加精确地控制注解的使用范围,从而提高代码的可读性和可维护性。
注解的属性设置默认值
注解的属性可以设置默认值。在Java注解中,我们可以为属性指定默认值,这样在使用注解时,如果没有为属性赋值,就会使用默认值。
为注解属性设置默认值非常简单,只需要在注解属性声明时为其赋值即可。例如,下面是一个定义了默认值的注解示例:
public @interface MyAnnotation {String name() default "John";int age() default 30;
}
在这个注解中,有两个属性:name
和age
,分别对应String
类型和int
类型。同时,这两个属性都有默认值,name
的默认值为"John"
,age
的默认值为30
。
在使用注解时,我们可以只为部分属性赋值,未赋值的属性将使用默认值。例如,下面是一个使用@MyAnnotation
注解的示例:
@MyAnnotation(name = "Jane")
public class MyClass {// ...
}
在这个例子中,我们在MyClass
类上使用了@MyAnnotation
注解,并为name
属性赋值为"Jane"
。由于我们没有为age
属性赋值,所以age
属性将使用默认值30
。
如果我们要获取注解属性的值,可以使用反射机制访问注解实例的属性。例如,下面是一个示例,演示了如何使用反射访问@MyAnnotation
注解的属性:
MyAnnotation annotation = MyClass.class.getAnnotation(MyAnnotation.class);
String name = annotation.name(); // "Jane"
int age = annotation.age(); // 30
在这个示例中,我们使用反射来获取MyClass
类上的@MyAnnotation
注解,并访问其name
和age
属性的值。由于我们为name
属性赋值为"Jane"
,所以name
属性的值为"Jane"
,而age
属性的值为默认值30
。
因此,注解的属性可以设置默认值,这样在使用注解时,如果没有为属性赋值,就会使用默认值。
相关文章:
特殊的类之注解
注解🚙注解的入门和作用以及原理示例注解的方法名就是属性名Retention的作用Target的作用注解的属性设置默认值天生我材必有用,千金散尽还复来。——唐代李白《将进酒》 在Java中,注解实际上是特殊类型的接口,当我们使用注解时&am…...
商业分享:盲盒电商开启电商新可能
盲盒,顾名思义,一个看不出里面装着什么东西的盒子。当你看不见盲盒里的商品时,你会思考盲盒里可能装着什么,它会诱发你的好奇心,而在好奇心的促使下,你会不由自主地买一个拆开来看,刚好大多数盲…...

【计算机架构】如何计算 CPU 时间
目录 0x00 响应时间和吞吐量(Response Time and Throughput) 0x01 相对性能(Relative Performance) 0x02 执行时间测量(Measuring Execution Time) 0x03 CPU 时钟(Clocking) 0x…...

银行数字化转型导师坚鹏:银行行长如何进行数字化转型
银行行长如何进行数字化转型 ——数字化转型背景下重塑银行行长核心竞争力 授课背景: 很多银行存在以下问题:银行行长不知道如何进行数字化转型?银行行长不清楚银行数字化能力模型的内涵?银行行长不知道如何通过数字化转型提…...

N32G45x学习笔记--- gpio引脚复用
关于gpio的引脚复用需要开启复用时钟 RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE);官方引脚复用: 芯片上电默认使能 SWD-JTAG 调试接口,调试接口被映射到 GPIO 端口上 禁止 JTAG 使能SWJ-DP /* 禁止 JTAG 使能SWJ-DP */GPIO_ConfigPinRemap(GPIO_RMP_SW_JTAG_S…...

ArcGIS Pro中使用深度学习的高分辨率土地覆盖制图
本文非常详细的讲解了利用深度学习在高分辨率土地覆盖制图的应用,本文作者:Amin Tayyebi,文章从数据准备到训练U-Net模型等等细节都有讲解。本译文只是使用谷歌翻译而成。文章可能有错误语句及不通顺情况,所以仅供参考学习。有需要…...
【学习笔记】「NOI2018」冒泡排序
从题解的角度来说,这是一道简单题。不过考场上在没有任何人提示的情况下要想出正确的结论其实并不容易。 我自己做这道题的时候,因为没有想清楚题目给出的下界能取到的充要条件是什么,所以到了很晚才猜到结论,以至于难以为继。 …...

【Ruby学习笔记】3.Ruby 语法及数据类型
前言 本章介绍Ruby的语法和数据类型。 Ruby 语法 让我们编写一个简单的 Ruby 程序。所有的 Ruby 文件扩展名都是 .rb。所以,把下面的源代码放在 test.rb 文件中。 实例 #!/usr/bin/ruby -wputs "Hello, Ruby!";在这里,假设您的 /usr/bin …...

华为OD机试题【字符匹配】用 Java 解 | 含解题说明
华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典本篇题目:字符匹配 题目 给你一个字符串…...
JavaScript数组对象的浅拷贝与深拷贝(二)实现对象深拷贝的方法(5种)
JavaScript实现对象深拷贝的方法(5种)知识回调(不懂就看这儿!)场景复现实现对象深拷贝的五种方法1.json暴力转化2.es6扩展运算符3.for in循环遍历对象4.Object.assign()对象的合并5.利用循环和递归的方式实现对象浅拷贝…...

iPhone屏幕适配(之屏幕尺寸)
Device screen size 各设备屏幕尺寸 DeviceDimensions (portrait)iPhone 14 Pro Max430x932 pt (1290x2796 px 3x)iPhone 14 Pro393x852 pt (1179x2556 px 3x)iPhone 14 Plus428x926 pt (1284x2778 px 3x)iPhone 14390x844 pt (1170x2532 px 3x)iPhone 13 Pro Max428x926 pt (…...

手机变砖修复神器之 8 个的 Android手机系统修复工具
如果您经常在 Android 设备上遇到问题,则需要找到最好的 Android 系统修复应用程序并使用它来一劳永逸地解决您的问题。如果您不确定执行此操作的好应用是什么,我们在这里为您列出了一些最好的 Android 修复软件。 虽然现在出货的 Android 手机相当稳定…...

稀疏矩阵(Sparse Matrix)
1.背景 在数据科学和深度学习等领域常会采用矩阵格式来存储数据,但当矩阵较为庞大且非零元素较少时, 如果依然使用dense的矩阵进行存储和计算将是极其低效且耗费资源的。所以,通常我们采用Sparse稀疏矩阵的方式来存储矩阵,提高存储…...

深度学习中的损失函数
文章目录一. Loss函数1. 均方差损失(Mean Squared Error Loss)2. 平均绝对误差损失(Mean Absolute Error Loss)3.(Huber Loss)4. 分位数损失(Quantile Loss)5. 交叉熵损失࿰…...
English Learning - L2 语音作业打卡 辅音咬舌音 [θ] [ð] Day29 2023.3.21 周二
English Learning - L2 语音作业打卡 辅音咬舌音 [θ] [] Day29 2023.3.21 周二💌发音小贴士:💌当日目标音发音规则/技巧:🍭 Part 1【热身练习】🍭 Part2【练习内容】🍭【练习感受】🍓元音 [θ]…...
【原始者-综述】
目录知识框架No.1 AcwingNo.2 LeetcodeNo.3 PTANo.4 蓝桥No.5 牛客网No.6 代码随想录知识框架 No.1 Acwing 那就点击这里转向自己的Acwing题解咯 单调栈,动态规划,贪心,回溯,二叉树,站与队列,双指针&#…...

C++内存模型
目录 一.内存分区 二,分区顺序 1 程序运行前 2 程序运行后 3.new操作符 一.内存分区 内存分区意义:不同区域存放的数据,赋予不同的生命周期, 给我们更大的灵活编程 内存可以分为以下几个区: 代码区:存放函数体的二进制代码…...

八股+面经
文章目录项目介绍Java基础MapHashMap v.s Hashtable(5点)ConcurrentHashMap v.s Hashtable(2点)代理模式1. 静态代理2. 动态代理2.1 JDK 动态代理机制2.2 CGLIB 动态代理机制Java并发线程volatilesynchronized线程池JVM类加载机制垃圾回收(GC)1. 引用类型…...

MySQL更新数据流程
1.mysql三种重要日志 redo log(重做日志):存在于引擎层,物理存储,通过设置innodb_flush_log_at_trx_xommit1 让其持久化到磁盘,保证引擎的crash-safe能力,遵从WAL技术(Write-Ahead …...

测试开发进阶系列课程
测试开发系列课程1.完善程序思维--------案列:图书管理系统的创建**(一)图书管理系统的创建**1.完善程序思维--------案列:图书管理系统的创建 (一)图书管理系统的创建 1.在main中写入主函数,…...
基于算法竞赛的c++编程(28)结构体的进阶应用
结构体的嵌套与复杂数据组织 在C中,结构体可以嵌套使用,形成更复杂的数据结构。例如,可以通过嵌套结构体描述多层级数据关系: struct Address {string city;string street;int zipCode; };struct Employee {string name;int id;…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础
第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...
命令行关闭Windows防火墙
命令行关闭Windows防火墙 引言一、防火墙:被低估的"智能安检员"二、优先尝试!90%问题无需关闭防火墙方案1:程序白名单(解决软件误拦截)方案2:开放特定端口(解决网游/开发端口不通)三、命令行极速关闭方案方法一:PowerShell(推荐Win10/11)方法二:CMD命令…...

HTTPS证书一年多少钱?
HTTPS证书作为保障网站数据传输安全的重要工具,成为众多网站运营者的必备选择。然而,面对市场上种类繁多的HTTPS证书,其一年费用究竟是多少,又受哪些因素影响呢? 首先,HTTPS证书通常在PinTrust这样的专业平…...