反射(二)ReflectionUtils

devtools/2024/9/24 16:56:16/

一、介绍

1、简介

org.springframework.util.ReflectionUtils 是 Spring 框架提供的一个反射工具类,它封装了 Java 反射 API 的一些常用操作,使得我们能够更加方便、简洁地使用反射功能。

虽然 ReflectionUtils 提供了很多便捷的方法,但使用反射仍然需要谨慎。反射操作可能会破坏封装性、增加性能开销,并可能引发安全问题。因此,在不需要动态访问的情况下,最好避免使用反射。

二、API

1、获取 Class 对象

ReflectionUtils 提供了多种获取 Class 对象的方法,如:

(1)findClass(String name): 根据类名获取 Class 对象,与 Class.forName(String) 类似,但会缓存已经加载过的类。
(2)getClass(Object obj): 获取对象的运行时类,与 obj.getClass() 等效。
(3)getUserClass(Object obj): 如果对象是代理对象,则获取其背后的实际类(即目标类),否则与 getClass(Object) 相同。

2、访问字段(Field)

(1)findField(Class<?> clazz, String name): 在给定的类及其父类中查找具有指定名称的字段。

import org.springframework.util.ReflectionUtils;public class Person {private String name;public Person(String name) {this.name = name;}// 省略其他方法...
}public class ReflectionExample {public static void main(String[] args) {Person person = new Person("zs");String fieldName = "name";// 使用 ReflectionUtils 获取私有字段的值String nameValue = (String) ReflectionUtils.getFieldValue(person, fieldName);System.out.println("Name value: " + nameValue); // 输出: Name value: zs}
}

(2)findField(Class<?> clazz, String name, Class<?> type): 根据名称和类型查找字段。
(3)getField(Field field): 获取可访问的字段对象,如果字段是私有的,会设置其为可访问。

(4)setField(Object obj, String name, Object value): 设置指定对象的字段值。

public class ReflectionExample {public static void main(String[] args) {Person person = new Person("John Doe");String fieldName = "name";String newValue = "zs";// 使用 ReflectionUtils 设置私有字段的值ReflectionUtils.setField(person, fieldName, newValue);// 再次获取并验证字段值已更改String updatedValue = (String) ReflectionUtils.getFieldValue(person, fieldName);System.out.println("Updated name value: " + updatedValue); // 输出: Updated name value: zs}
}

(5)getFieldValue(Object obj, String name): 获取指定对象的字段值。

3、调用方法(Method)

(1)findMethod(Class<?> clazz, String name, Class<?>... paramTypes):

       查找具有指定名称和参数类型的方法。

Method method = ReflectionUtils.findMethod(aClass, methodName);

(2)invokeMethod(Method method, Object target): 调用无参数方法。

Object[] parameters = new Object[parameterTypes.length];
result = ReflectionUtils.invokeMethod(preCheckMethod, null, parameters);


(3)invokeMethod(Method method, Object target, Object... args): 调用带参数的方法。
(4)invokeJdbcMethod(Method method, Object target, Object... args):

      专为 JDBC 方法设计的调用,处理 SQL 异常。
(5)makeAccessible(Method method): 确保方法可以访问,即使它是私有的。

4、构造函数和实例化

(1)getConstructorIfAvailable(Class<?> clazz, Class<?>... paramTypes):

   尝试获取指定参数类型的构造函数,如果找不到则返回 null。
(2)instantiateClass(Constructor<?> ctor, Object... args): 使用指定的构造函数和参数实例化类。

(3)newInstance(Class<?> clazz, Object... args): 简化版的实例化方法,它内部会查找合适的构造函数并调用 instantiateClass。

5、其他实用方法

(1)isAssignable(Class<?> lhsType, Class<?> rhsType): 判断一个类是否可以赋值给另一个类(考虑继承关系)。
(2)doesMethodDeclareException(Method method, Class<?> exceptionType):

  检查方法是否声明了指定类型的异常。

import org.springframework.util.ReflectionUtils;
import java.io.IOException;public class ExampleWithException {public void methodThatThrows() throws IOException {// ... 方法实现 ...}
}public class ReflectionExample {public static void main(String[] args) {boolean declaresException = ReflectionUtils.doesMethodDeclareException(ReflectionUtils.findMethod(ExampleWithException.class, "methodThatThrows"), IOException.class);System.out.println("Declares IOException: " + declaresException); // 输出: Declares IOException: true}
}

(3)getUniqueDeclaredMethods(Class<?> leafClass): 获取类中声明的所有方法,包括继承的方法,但排除重写的方法,确保每个方法只出现一次。
(4)getAllDeclaredMethods(Class<?> leafClass): 获取类中声明的所有方法,包括继承的方法,但不排除重写的方法。
(5)getDeclaredMethods(Class<?> clazz): 获取类中直接声明的所有方法,不包括继承的方法。
(6)getDeclaredFields(Class<?> clazz): 获取类中直接声明的所有字段。

Method method = ReflectionUtils.findMethod(aClass, methodName);

http://www.ppmy.cn/devtools/116590.html

相关文章

docker-compose集群(单机多节点)环境搭建与使用

此方案已经经过生产环境验证&#xff0c;可放心大胆使用如果喜欢&#xff0c;欢迎点赞&#x1f44d;收藏❤️评论噢&#xff5e; 略去 Docker 和 Docker Compose 安装部分,如果有需要的同学&#xff0c;可以评论&#xff0c;创建 docker-compose.yml 文件并配置 Nacos 集群和 M…

Go 综合题面试题

1. Golang 中 make 和 new 的区别&#xff1f; #make 和 new 都用于内存分配1&#xff1a;接收参数个数不一样&#xff1a; new() 只接收一个参数&#xff0c;而 make() 可以接收3个参数2&#xff1a;返回类型不一样&#xff1a; new() 返回一个指针&#xff0c;而 make() 返回…

【Java面向对象高级06】static的应用知识:代码块

文章目录 前言一、代码块概述二、代码块分2种 1、静态代码块2、实例代码块总结 前言 记录static的应用知识&#xff1a;代码块 一、代码块概述 代码块是类的5大成分之一&#xff08;成员变量&#xff0c;构造器&#xff0c;方法&#xff0c;代码块&#xff0c;内部类&#xf…

使用 Higress AI 插件对接通义千问大语言模型

前言 什么是 AI Gateway AI Gateway 的定义是 AI Native 的 API Gateway&#xff0c;是基于 API Gateway 的能⼒来满⾜ AI Native 的需求。例如&#xff1a; 将传统的 QPS 限流扩展到 token 限流。将传统的负载均衡/重试/fallback 能力延伸&#xff0c;支持对接多个大模型厂…

golang学习笔记27——golang 实现 RPC 模块

推荐学习文档 golang应用级os框架&#xff0c;欢迎stargolang应用级os框架使用案例&#xff0c;欢迎star案例&#xff1a;基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识&#xff0c;这里有免费的golang学习笔…

2024年【N2观光车和观光列车司机】复审考试及N2观光车和观光列车司机实操考试视频

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 N2观光车和观光列车司机复审考试是安全生产模拟考试一点通总题库中生成的一套N2观光车和观光列车司机实操考试视频&#xff0c;安全生产模拟考试一点通上N2观光车和观光列车司机作业手机同步练习。2024年【N2观光车和…

JZ2440开发板——S3C2440的UART

以下内容源于韦东山课程的学习与整理&#xff0c;如有侵权请告知删除。 一、UART硬件简介 UART&#xff0c;全称是“Universal Asynchronous Receiver Transmitter”&#xff0c;即“通用异步收发器”&#xff0c;也就是我们日常说的“串口”。 它在嵌入式中用途非常广泛&…

介绍GPT-o1:一系列解决困难问题( science, coding, and math )的推理模型

openai o1介绍 一、官方技术报告要点剖析实验1 benchmark分析实验2:和phd比赛技术细节&#xff1a;Chain of Thought的使用人类偏好评估Human preference evaluationsatety技术细节&#xff1a;隐藏思维链为监控模型提供了机会:)openai的几点conclusion 二、官方介绍剖析 Intro…