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

特殊的类之注解

注解🚙

    • 注解的入门和作用以及原理
      • 示例
      • 注解的方法名就是属性名
      • @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();
}

在这个注解中,有两个属性:nameage,分别对应String类型和int类型。

我们可以通过使用注解并传入属性值来使用它。例如,下面的代码演示了如何使用上述注解:

@MyAnnotation(name = "John Doe", age = 30)
public class MyClass {// ...
}

在这个例子中,我们在MyClass类上使用了@MyAnnotation注解,并传入了nameage属性的值。这些值会在编译时存储在注解实例中,以便在运行时访问。

在访问注解属性时,我们可以像调用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注解有三种保留策略:

  1. RetentionPolicy.SOURCE:注解只在源代码中保留,在编译时会被忽略。

  2. RetentionPolicy.CLASS:注解在编译时会被保留,但在运行时不可用。

  3. 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;
}

在这个注解中,有两个属性:nameage,分别对应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注解,并访问其nameage属性的值。由于我们为name属性赋值为"Jane",所以name属性的值为"Jane",而age属性的值为默认值30

因此,注解的属性可以设置默认值,这样在使用注解时,如果没有为属性赋值,就会使用默认值。

相关文章:

特殊的类之注解

注解&#x1f699;注解的入门和作用以及原理示例注解的方法名就是属性名Retention的作用Target的作用注解的属性设置默认值天生我材必有用&#xff0c;千金散尽还复来。——唐代李白《将进酒》 在Java中&#xff0c;注解实际上是特殊类型的接口&#xff0c;当我们使用注解时&am…...

商业分享:盲盒电商开启电商新可能

盲盒&#xff0c;顾名思义&#xff0c;一个看不出里面装着什么东西的盒子。当你看不见盲盒里的商品时&#xff0c;你会思考盲盒里可能装着什么&#xff0c;它会诱发你的好奇心&#xff0c;而在好奇心的促使下&#xff0c;你会不由自主地买一个拆开来看&#xff0c;刚好大多数盲…...

【计算机架构】如何计算 CPU 时间

目录 0x00 响应时间和吞吐量&#xff08;Response Time and Throughput&#xff09; 0x01 相对性能&#xff08;Relative Performance&#xff09; 0x02 执行时间测量&#xff08;Measuring Execution Time&#xff09; 0x03 CPU 时钟&#xff08;Clocking&#xff09; 0x…...

银行数字化转型导师坚鹏:银行行长如何进行数字化转型

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

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中使用深度学习的高分辨率土地覆盖制图

本文非常详细的讲解了利用深度学习在高分辨率土地覆盖制图的应用&#xff0c;本文作者&#xff1a;Amin Tayyebi&#xff0c;文章从数据准备到训练U-Net模型等等细节都有讲解。本译文只是使用谷歌翻译而成。文章可能有错误语句及不通顺情况&#xff0c;所以仅供参考学习。有需要…...

【学习笔记】「NOI2018」冒泡排序

从题解的角度来说&#xff0c;这是一道简单题。不过考场上在没有任何人提示的情况下要想出正确的结论其实并不容易。 我自己做这道题的时候&#xff0c;因为没有想清楚题目给出的下界能取到的充要条件是什么&#xff0c;所以到了很晚才猜到结论&#xff0c;以至于难以为继。 …...

【Ruby学习笔记】3.Ruby 语法及数据类型

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

华为OD机试题【字符匹配】用 Java 解 | 含解题说明

华为Od必看系列 华为OD机试 全流程解析+经验分享,题型分享,防作弊指南华为od机试,独家整理 已参加机试人员的实战技巧华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典本篇题目:字符匹配 题目 给你一个字符串…...

JavaScript数组对象的浅拷贝与深拷贝(二)实现对象深拷贝的方法(5种)

JavaScript实现对象深拷贝的方法&#xff08;5种&#xff09;知识回调&#xff08;不懂就看这儿&#xff01;&#xff09;场景复现实现对象深拷贝的五种方法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 设备上遇到问题&#xff0c;则需要找到最好的 Android 系统修复应用程序并使用它来一劳永逸地解决您的问题。如果您不确定执行此操作的好应用是什么&#xff0c;我们在这里为您列出了一些最好的 Android 修复软件。 虽然现在出货的 Android 手机相当稳定…...

稀疏矩阵(Sparse Matrix)

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

深度学习中的损失函数

文章目录一. Loss函数1. 均方差损失&#xff08;Mean Squared Error Loss&#xff09;2. 平均绝对误差损失&#xff08;Mean Absolute Error Loss&#xff09;3.&#xff08;Huber Loss&#xff09;4. 分位数损失&#xff08;Quantile Loss&#xff09;5. 交叉熵损失&#xff0…...

English Learning - L2 语音作业打卡 辅音咬舌音 [θ] [ð] Day29 2023.3.21 周二

English Learning - L2 语音作业打卡 辅音咬舌音 [θ] [] Day29 2023.3.21 周二&#x1f48c;发音小贴士&#xff1a;&#x1f48c;当日目标音发音规则/技巧:&#x1f36d; Part 1【热身练习】&#x1f36d; Part2【练习内容】&#x1f36d;【练习感受】&#x1f353;元音 [θ]…...

【原始者-综述】

目录知识框架No.1 AcwingNo.2 LeetcodeNo.3 PTANo.4 蓝桥No.5 牛客网No.6 代码随想录知识框架 No.1 Acwing 那就点击这里转向自己的Acwing题解咯 单调栈&#xff0c;动态规划&#xff0c;贪心&#xff0c;回溯&#xff0c;二叉树&#xff0c;站与队列&#xff0c;双指针&#…...

C++内存模型

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

八股+面经

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

MySQL更新数据流程

1.mysql三种重要日志 redo log&#xff08;重做日志&#xff09;&#xff1a;存在于引擎层&#xff0c;物理存储&#xff0c;通过设置innodb_flush_log_at_trx_xommit1 让其持久化到磁盘&#xff0c;保证引擎的crash-safe能力&#xff0c;遵从WAL技术&#xff08;Write-Ahead …...

测试开发进阶系列课程

测试开发系列课程1.完善程序思维--------案列&#xff1a;图书管理系统的创建**&#xff08;一&#xff09;图书管理系统的创建**1.完善程序思维--------案列&#xff1a;图书管理系统的创建 &#xff08;一&#xff09;图书管理系统的创建 1.在main中写入主函数&#xff0c;…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数

高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...