java注解与反射(非常详细, 带有很多样例)
下面是详细地讲解 Java 中的注解与反射,并提供了很多的示例来帮助理解。
Java 注解(Annotations)
1. 注解的基本概念
注解(Annotation)是 Java 5 引入的一种用于为代码元素(类、方法、字段、参数等)添加元数据的机制。这些元数据可以在编译时、类加载时或运行时被读取并使用。注解不会直接影响代码的执行,但可以通过工具或框架来处理这些元数据,以实现一些功能。
2. 内置注解
Java 提供了一些常用的内置注解:
@Override:用于标注方法,表明该方法重写了父类的方法。@Deprecated:用于标注过时的元素,编译器看到使用了这个元素会发出警告。@SuppressWarnings:用于抑制编译器警告。
public class AnnotationExample {@Overridepublic String toString() {return "AnnotationExample";}@Deprecatedpublic void deprecatedMethod() {// 这个方法已经过时}@SuppressWarnings("unchecked")public void suppressWarningsExample() {List rawList = new ArrayList();rawList.add("example");}
}
3. 自定义注解
你可以定义自己的注解,并通过元注解(meta-annotation)来指定注解的行为。
元注解:
@Retention:指定注解的保留策略,取值有RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME。@Target:指定注解可以应用的程序元素,取值有ElementType.TYPE、ElementType.FIELD、ElementType.METHOD、ElementType.PARAMETER等。@Documented:指定注解是否包含在 Javadoc 中。@Inherited:指定注解是否可以被子类继承。
import java.lang.annotation.*;@Retention(RetentionPolicy.RUNTIME) // 运行时保留
@Target(ElementType.METHOD) // 作用于方法
public @interface MyAnnotation {String value();
}public class MyClass {// 当 MyClass 的 myMethod 方法被注释了这个注解后,可以通过反射在运行时获取这个注解及其值。下面的"结合注解与反射"有例子@MyAnnotation(value = "example")public void myMethod() {System.out.println("Method with MyAnnotation");}
}
Java 反射(Reflection)
1. 反射的基本概念
反射是一种运行时机制,允许程序在运行时检查和操作类、方法、字段等。通过反射,你可以:
- 获取类的详细信息(类名、修饰符、父类、接口等)。
- 获取类的方法、构造函数、字段等。
- 动态调用方法或构造函数。
- 动态访问和修改字段的值。
2. 获取类的信息
- 获取 Class 对象
有多种方法可以获取一个类的 Class 对象:
Class.forName(String className): 通过类的完全限定名获取 Class 对象。
ClassName.class: 通过类的字面常量获取 Class 对象。
object.getClass(): 通过对象实例获取 Class 对象。
// 获取 Class 对象的三种方式
Class<?> clazz1 = Class.forName("java.util.ArrayList");
Class<?> clazz2 = ArrayList.class;
ArrayList<String> list = new ArrayList<>();
Class<?> clazz3 = list.getClass();
3. 获取类的成员
getDeclaredFields(): 获取类的所有字段(包括私有字段)。
getDeclaredMethods(): 获取类的所有方法(包括私有方法)。
getDeclaredConstructors(): 获取类的所有构造函数。
getField(String name): 获取类的指定字段(不包括私有字段)。
getMethod(String name, Class<?>... parameterTypes): 获取类的指定方法(不包括私有方法)。
getConstructor(Class<?>... parameterTypes): 获取类的指定构造函数。
Class<?> clazz = Class.forName("java.util.ArrayList");// 获取所有声明的字段
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {System.out.println("字段: " + field.getName());
}// 获取所有声明的方法
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {System.out.println("方法: " + method.getName());
}// 获取所有声明的构造函数
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
for (Constructor<?> constructor : constructors) {System.out.println("构造函数: " + constructor.getName());
}
4. 动态创建对象
newInstance(): 使用无参构造函数创建对象。
Constructor.newInstance(Object... initargs): 使用指定构造函数创建对象。
Class<?> clazz = Class.forName("java.util.ArrayList");// 使用无参构造函数创建对象
Object obj1 = clazz.newInstance();// 使用带参数的构造函数创建对象
Constructor<?> constructor = clazz.getConstructor(Collection.class);
Collection<String> collection = Arrays.asList("A", "B", "C");
Object obj2 = constructor.newInstance(collection);System.out.println(obj1);
System.out.println(obj2);
5. 动态调用方法
Method.invoke(Object obj, Object... args): 调用指定对象的该方法。
Class<?> clazz = Class.forName("java.util.ArrayList");
Method method = clazz.getMethod("add", Object.class);ArrayList<String> list = new ArrayList<>();
method.invoke(list, "Hello");
System.out.println(list); // 输出: [Hello]
6. 动态访问和修改字段
Field.get(Object obj): 获取指定对象中此字段的值。
Field.set(Object obj, Object value): 设置指定对象中此字段的值。
class MyClass {private String field = "Initial Value";
}Class<?> clazz = Class.forName("MyClass");
Field field = clazz.getDeclaredField("field");
field.setAccessible(true); // 如果字段是私有的,需要设置可访问MyClass obj = new MyClass();
System.out.println("原始字段值: " + field.get(obj)); // 获取字段值field.set(obj, "New Value"); // 设置字段值
System.out.println("修改后的字段值: " + field.get(obj)); // 获取字段值
结合注解与反射
注解与反射的结合非常常见,尤其在框架中,例如 Spring 和 Hibernate。通过反射机制,你可以在运行时读取注解信息,并根据这些信息执行特定的操作。
示例:简单的依赖注入
以下示例展示了如何通过注解和反射实现简单的依赖注入:
import java.lang.annotation.*;
import java.lang.reflect.*;// 定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface Inject {
}// 服务类
class Service {public void serve() {System.out.println("Service is serving");}
}// 客户端类
class Client {@Injectprivate Service service;public void doSomething() {service.serve();}
}// 注入依赖的工具类
public class DependencyInjector {public static void main(String[] args) throws Exception {Client client = new Client();injectDependencies(client);client.doSomething();}public static void injectDependencies(Object obj) throws Exception {Class<?> clazz = obj.getClass();for (Field field : clazz.getDeclaredFields()) { // 遍历client的所有字段(变量).if (field.isAnnotationPresent(Inject.class)) { // 获取带有Inject注解的变量, 把它注入到 Client 中field.setAccessible(true);Object dependency = field.getType().getConstructor().newInstance();field.set(obj, dependency); // 通过field的set方法将service实例注入到client中}}}
}
在这个示例中:
@Inject注解用于标注需要注入的字段。DependencyInjector类通过反射获取Client类中带有@Inject注解的字段,并动态实例化Service类的对象,注入到Client类的实例中。Client类调用doSomething方法时,Service类的实例已经被注入并可以使用。
总结
注解和反射是 Java 中非常强大和灵活的机制,通过它们可以实现许多高级功能,例如依赖注入、AOP、动态代理等。在实际开发中,理解和熟练运用这些技术,可以帮助你编写出更加灵活、可扩展的代码。
文章到这里就这束了!~
其他文章地址:
快速入门,springboot知识点汇总
springboot常用注解大全(超详细, 30个)
springboot websocket知识点汇总
spring cloud知识点汇总, 待更
相关文章:
java注解与反射(非常详细, 带有很多样例)
下面是详细地讲解 Java 中的注解与反射,并提供了很多的示例来帮助理解。 Java 注解(Annotations) 1. 注解的基本概念 注解(Annotation)是 Java 5 引入的一种用于为代码元素(类、方法、字段、参数等&…...
模拟实现短信登录功能 (session 和 Redis 两种代码实例) 带前端演示
目录 整体流程 发送验证码 短信验证码登录、注册 校验登录状态 基于 session 实现登录 实现发送短信验证码功能 1. 前端发送请求 2. 后端处理请求 3. 演示 实现登录功能 1. 前端发送请求 2. 后端处理请求 校验登录状态 1. 登录拦截器 2. 注册拦截器 3. 登录完整…...
C# Parallel设置最大并发度
背景 以前用Parallel都是直接用,今天在处理pdf时发现不是很快,特别是有时居然卡死了,异常是有处理的,但没有爆出来,不知道问题在哪。 老老实实不用多线程,一个多小时觉得还是太累。 用的话,部…...
【java】力扣 反转字符串中的单词
目录 题目描述题目描述思路代码 题目描述 151.反转字符串中的单词 题目描述 思路 主要是利用快慢指针和字符串的截取 还要了解去掉首尾空格的函数是trim 那s"the sky is blue"举例 这个例子是没有首尾空格的,以防万一,我们不管有没有&#…...
科学设计程序员面试内容,破解“八股文”之弊
“八股文”在实际工作中是助力、阻力还是空谈? 作为现在各类大中小企业面试程序员时的必问内容,“八股文”似乎是很重要的存在。但“八股文”是否能在实际工作中发挥它“敲门砖”应有的作用呢?有IT人士不禁发出疑问:程序员面试考…...
蓝牙BlueZ验证使用记录
最近使用的一款AICSemi AIC8800D8芯片做的WiFiBT二合一模组,该模组WiFi使用SDIO通信,BT使用UART通信,供应商丢了一份驱动,包含了三个目录:aic8800_bsp、aic8800_fdrv和aic8800_btlpm,而蓝牙部分提供了lbh_s…...
【从0制作自己的ros导航小车:上位机篇】02、ros1多机通讯与坐标变换可视化
从0制作自己的ros导航小车 前言一、ros1多机通讯二、rviz可视化小车坐标系 前言 上节课完成了里程计数据与坐标变换发布,但是还没有测试,本节进行测试,测试之前需要知道一件事,上位机也就是开发板一般不做可视化用,因…...
JumpServer关闭admin mfa验证
背景 因为上一次启动了mfa验证,但是没有验证就关机重启,导致再开机输入密码后需要mfa绑定,但是怎么也无法绑定成功,导致无法登录。 故希望通过后台取消mfa的验证 解决方法 1. 进入docker docker exec -it jms_core /bin/bash…...
Kafka知识总结(选举机制+控制器+幂等性)
文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 文章收录在网站:http://hardyfish.top/ 选举机制 控制器(Broker)选举 控制器就是…...
2024非常全的接口测试面试题及参考答案-软件测试工程师没有碰到算我输!
一、前言 接口测试最近几年被炒的火热了,越来越多的测试同行意识到接口测试的重要性。接口测试为什么会如此重要呢? 主要是平常的功能点点点,大家水平都一样,是个人都能点,面试时候如果问你平常在公司怎么测试的&#…...
python 写一个年会抽奖的demo
使用while 进行循环,进行三轮之后,停止。random.sample() 抽样不重复查询数据 import random name_list [] for i in range(0,100): name_list .append(员工{i}) winnerNum [30,6,3] //每个中奖人数 count 0 while count < 3: choice i…...
C++ OpenCV 实现多张图片叠加 叠加文字
C OpenCV 实现多张图片叠加 叠加文字 在C中使用OpenCV叠加多张图片以及添加文字的基本步骤如下: 加载多张图片。 确定叠加位置。 使用cv::addWeighted叠加图片,可以为叠加的图片添加透明度。 使用cv::putText在图片上添加文字。 显示或保存结果图片…...
用 apifox cli 命令行运行本地接口出现TypeError:Invalid IP address: undefined
用 apifox cli 命令行运行本地接口出现TypeError:Invalid IP address: undefined,客户端运行是通过的但命令行运行会报错 修改端口也是一样报错,地址修改为127.0.0.1会报错connect ECONNREFUSED 127.0.0.1:8080 解决方法:不用localhost&…...
PyQt6简易案例代码GUI界面小工具——实现增、删、查、改(练手正合适)
目录 专栏导读1、库的介绍PyQt6的主要特点包括:使用PyQt6开发应用程序的一般步骤:库的安装 2、设计窗口设计列表视图设计输入框控件与按钮设计布局listView的简单样式增删查改函数 完整代码总结 专栏导读 🌸 欢迎来到Python办公自动化专栏—P…...
JavaScript快速入门指南
JavaScript是一种广泛应用于网页开发的脚本语言,它可以让网页实现动态效果和交互性。无论是前端开发还是全栈开发,JavaScript都是不可或缺的一部分。本文将带你快速入门JavaScript,从基础语法到实际应用,让你快速上手这门强大的语…...
Esbuild介绍
Esbuild是一个由Evan Wallace基于Go语言开发的快速、可扩展的JavaScript和CSS打包器及压缩器。它以其极快的构建速度和高效的性能在众多构建工具中脱颖而出。 一、核心特性 超快的构建速度: Esbuild相比传统的构建工具(如Webpack)在构建速度…...
UnityShaderUI编辑器扩展
前言: 当我们在制作通用Shader的时候,避免不了许多参数混杂在一起,尽管在材质面板已经使用过Header标签来区分,但是较长的Shader参数就会导致冗余,功能块不够简约明了,如图: 对于Shader制作者来…...
分布式事务——2PC 代码示例
一 2PC代码示例 在Java中实现两阶段提交(2PC, Two-Phase Commit)协议通常涉及多个组件,包括事务协调者(Transaction Coordinator)和多个资源管理器(Resource Managers,如数据库)。在…...
vue实现简易的全局加载动画效果
效果展示 思路 封装一个组件,放Img,伪类样式,固定在屏幕fixed 然后App应用这个组件,Z index拉最大,防止用户在加载动画时乱点, v-show绑定loading,该数据可以放vuex还是任一的公共状态管理变…...
Linux网络工具“瑞士军刀“集合
一、背景 平常我们在进行Linux服务器相关运维的时候,总会遇到一些网络相关的问题。我们可以借助这些小巧、功能强悍的工具帮助我们排查问题、解决问题。 下面结合之前的一些使用经验为大家介绍一下一些经典应用场景下,这个网络命令工具如何使用的。例如怎…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
Leetcode 3577. Count the Number of Computer Unlocking Permutations
Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接:3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯,要想要能够将所有的电脑解锁&#x…...
【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验
系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
C++ 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
