一、工具类代码
继承hutool 包的 ReflectUtil 反射工具类,只要方法有:
- 获取构造方法
- 关于字段的操作(获取字段名称、 修饰符、 值)
- 关于公共方法的操作
- 实例化
- 判断方法属性
- 执行方法
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ReflectUtils extends ReflectUtil {
private static final String SETTER_PREFIX = "set";
private static final String GETTER_PREFIX = "get";
/**
* 调用Getter方法.
* 支持多级,如:对象名.对象名.方法
*/
@SuppressWarnings("unchecked")
public static <E> E invokeGetter(Object obj, String propertyName) {
Object object = obj;
for (String name : StringUtils.split(propertyName, ".")) {
String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name);
object = invoke(object, getterMethodName);
}
return (E) object;
}
/**
* 调用Setter方法, 仅匹配方法名。
* 支持多级,如:对象名.对象名.方法
*/
public static <E> void invokeSetter(Object obj, String propertyName, E value) {
Object object = obj;
String[] names = StringUtils.split(propertyName, ".");
for (int i = 0; i < names.length; i++) {
if (i < names.length - 1) {
String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(names[i]);
object = invoke(object, getterMethodName);
} else {
String setterMethodName = SETTER_PREFIX + StringUtils.capitalize(names[i]);
Method method = getMethodByName(object.getClass(), setterMethodName);
invoke(object, method, value);
}
}
}
}
二、测试反射获取属性、属性值等
package com.ruoyi.demo;
import cn.hutool.core.lang.Console;
import cn.hutool.core.lang.Filter;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import java.lang.reflect.Field;
/**
* <简述>
* <详细描述>
*
* @author syf
* @date 2024年08月19日 14:59
*/
public class TestReflectUtils {
// Teacher类
static class Teacher{
private String name;
private int age;
}
public static void main(String[] args) {
testReflect();
}
//反射操作
static void testReflect(){
// 获取Teacher类的所有字段
Field[] fields = ReflectUtils.getFields(Teacher.class);
for (Field field :fields) {
Console.log("STAR---------------------------------------------------------------");
Console.log("getFields-获取Teacher类的所有字段:", field);
// 获取字段名
Console.log("getFieldName->获取字段名:",ReflectUtils.getFieldName(field));
// 获取字段值
Console.log("getFieldValue->获取字段值:",ReflectUtils.getFieldValue(new Teacher(),field));
// 获取字段修饰符
Console.log("getModifiers->获取字段修饰符:",field.getModifiers());
// 获取字段类型
Console.log("getType->获取字段类型:",field.getType());
Console.log("END---------------------------------------------------------------\n");
}
Console.log("STAR---------------------------------------------------------------");
// 获取Teacher类的所有字段,返回age字段
Field[] fields1 = ReflectUtils.getFields(Teacher.class, field -> "age".equals(field.getName()));
for (Field field :fields1) {
Console.log("getFields-返回age字段:", field);
}
Console.log("END---------------------------------------------------------------\n");
//获取单个字段
Field field = ReflectUtils.getField(Teacher.class, "age");
Console.log("getField-获取单个字段:", field);
}
}
打印结果:
STAR---------------------------------------------------------------
getFields-获取Teacher类的所有字段: private java.lang.String com.ruoyi.demo.TestReflectUtils$Teacher.name
getFieldName->获取字段名: name
getFieldValue->获取字段值: null
getModifiers->获取字段修饰符: 2
getType->获取字段类型: class java.lang.String
END---------------------------------------------------------------
STAR---------------------------------------------------------------
getFields-获取Teacher类的所有字段: private int com.ruoyi.demo.TestReflectUtils$Teacher.age
getFieldName->获取字段名: age
getFieldValue->获取字段值: 0
getModifiers->获取字段修饰符: 2
getType->获取字段类型: int
END---------------------------------------------------------------
getFields-返回age字段: private int com.ruoyi.demo.TestReflectUtils$Teacher.age
END---------------------------------------------------------------
getField-获取单个字段: private int com.ruoyi.demo.TestReflectUtils$Teacher.age
Process finished with exit code 0
三、反射进行GET、SET操作
public class TestReflectUtils {
// Teacher类
static class Teacher{
private String name;
private int age;
private static final String sex = "男";
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) {
//testReflect();
testFieldGet();
}
/**
* <简述>get set 操作
* <详细描述>
* @author syf
* @date 2024/8/19 16:32
*/
static void testFieldGet(){
Field nameField = ReflectUtils.getField(Teacher.class, "name");
Teacher teacher = new Teacher();
teacher.setName("张三");
// 方式1
try {
// 设置字段的可访问性,否则私有属性访问不到
nameField.setAccessible(true);
String s = (String) nameField.get(teacher);
Console.log("get() = {}", s);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
//方式2
String fieldValue = (String) ReflectUtils.getFieldValue(teacher, nameField);
Console.log("getFieldValue->获取字段值:",fieldValue);
//方式3
String fieldValue1 = (String) ReflectUtils.getFieldValue(teacher, "name");
Console.log("getFieldValue->获取字段值:",fieldValue1);
//设置值
ReflectUtils.setFieldValue(teacher, "name", "李四");
Console.log("setFieldValue->设置字段值:",ReflectUtils.getFieldValue(teacher, "name"));
ReflectUtils.setFieldValue(teacher, nameField, "王五");
Console.log("setFieldValue->设置字段值:",ReflectUtils.getFieldValue(teacher, "name"));
//获取final字段,修改value
//初始化前先移除 final,否则修改不了
ReflectUtils.removeFinalModify(ReflectUtils.getField(Teacher.class, "sex"));
Teacher teacherFinalSex = new Teacher();
ReflectUtils.setFieldValue(teacherFinalSex, "sex", "女");
Console.log("setFieldValue->设置字段值:",ReflectUtils.getFieldValue(teacherFinalSex, "sex"));
}
GET、SET操作结果:
注意操作final 修饰的属性时候,要在实例化前移除 final属性
get() = 张三
getFieldValue->获取字段值: 张三
getFieldValue->获取字段值: 张三
setFieldValue->设置字段值: 李四
setFieldValue->设置字段值: 王五
setFieldValue->设置字段值: 女
四、反射获取构造方法
public class TestReflectUtils {
// Teacher类
static class Teacher{
private String name;
private int age;
public Teacher() {
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
private static final String sex = "男";
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public static void main(String[] args) {
//testReflect();
// testFieldGet();
testConstructor();
}
static void testConstructor(){
// 获取所有构造方法
Constructor<Teacher>[] constructors = ReflectUtils.getConstructors(Teacher.class);
for (Constructor<Teacher> constructor : constructors){
Console.log("getConstructors->获取构造方法:",constructor);
}
// 获取无参构造方法
Constructor<Teacher> constructor = ReflectUtils.getConstructor(Teacher.class);
Console.log("getConstructor->获取无参构造方法:",constructor);
// 获取有参构造方法
Constructor<Teacher> constructor1 = ReflectUtils.getConstructor(Teacher.class, String.class, int.class);
Console.log("getConstructor->获取有参构造方法:",constructor1);
String name = constructor1.getName();
Console.log("name:{}",name);
int modifiers = constructor1.getModifiers();
Console.log("modifiers:{}",modifiers);
}
}
打印测试结果:
获取无参构造,有参构造,修改成员变量属性
getConstructors->获取构造方法: public com.ruoyi.demo.TestReflectUtils$Teacher()
getConstructors->获取构造方法: public com.ruoyi.demo.TestReflectUtils$Teacher(java.lang.String,int)
getConstructor->获取无参构造方法: public com.ruoyi.demo.TestReflectUtils$Teacher()
getConstructor->获取有参构造方法: public com.ruoyi.demo.TestReflectUtils$Teacher(java.lang.String,int)
name:com.ruoyi.demo.TestReflectUtils$Teacher
modifiers:1
五、 反射获取实例化
重写object 的toString 方法,打印参数
// Teacher类
static class Teacher{
private String name;
private int age;
public Teacher() {
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
private static final String sex = "男";
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return StringUtils.format("Teacher{name={}, age={}}", this.name, this.age);
}
}
public static void main(String[] args) {
//testReflect();
// testFieldGet();
//testConstructor();
testInstance();
}
/**
* <简述>实例化
* <详细描述>
* @author syf
* @date 2024/8/20 10:57
*/
static void testInstance(){
// 获取Teacher类的实例
Teacher teacher = ReflectUtils.newInstance(Teacher.class);
Console.log("newInstance->获取Teacher类的实例:",teacher);
// 获取Teacher类的实例,传入参数
Teacher teacher1 = ReflectUtils.newInstance(Teacher.class, "张三", 18);
Console.log("newInstance->获取Teacher类的实例,传入参数:",teacher1);
}
打印结果:
打印出实例化结果
newInstance->获取Teacher类的实例: Teacher{name=null, age=0}
newInstance->获取Teacher类的实例,传入参数: Teacher{name=张三, age=18}
六、反射获取成员方法
public class TestReflectUtils {
// Teacher类
static class Teacher{
private String name;
private int age;
public Teacher() {
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
private static final String sex = "男";
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return StringUtils.format("Teacher{name={}, age={}}", this.name, this.age);
}
}
public static void main(String[] args) {
//testReflect();
// testFieldGet();
//testConstructor();
//testInstance();
testMethod();
}
static void testMethod(){
Method[] methods = ReflectUtils.getMethods(Teacher.class);
for (Method method: methods) {
if (method.getDeclaringClass().isInstance(Object.class)){
Console.log("打印OBJECT的方法------------------------------------------------------------------------");
}
Console.log("getMethods->获取方法:",method);
}
Console.log("testMethod->获取方法:",ReflectUtils.getMethod(Teacher.class, "toString"));
}
}
打印结果:
打印自带的成员方法
也会打印object自带的方法
getMethods->获取方法: public java.lang.String com.ruoyi.demo.TestReflectUtils$Teacher.toString()
getMethods->获取方法: public java.lang.String com.ruoyi.demo.TestReflectUtils$Teacher.getName()
getMethods->获取方法: public void com.ruoyi.demo.TestReflectUtils$Teacher.setName(java.lang.String)
getMethods->获取方法: public int com.ruoyi.demo.TestReflectUtils$Teacher.getAge()
打印OBJECT的方法-----------------------------
getMethods->获取方法: protected void java.lang.Object.finalize() throws java.lang.Throwable
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final void java.lang.Object.wait() throws java.lang.InterruptedException
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
打印OBJECT的方法-----------------------------
getMethods->获取方法: public boolean java.lang.Object.equals(java.lang.Object)
打印OBJECT的方法-----------------------------
getMethods->获取方法: public native int java.lang.Object.hashCode()
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final native java.lang.Class java.lang.Object.getClass()
打印OBJECT的方法-----------------------------
getMethods->获取方法: protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final native void java.lang.Object.notify()
打印OBJECT的方法-----------------------------
getMethods->获取方法: public final native void java.lang.Object.notifyAll()
打印OBJECT的方法-----------------------------
getMethods->获取方法: private static native void java.lang.Object.registerNatives()
testMethod->获取方法: public java.lang.String com.ruoyi.demo.TestReflectUtils$Teacher.toString()
七、反射调用方法
public class TestReflectUtils {
// Teacher类
static class Teacher{
private String name;
private int age;
public Teacher() {
}
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
private static final String sex = "男";
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return StringUtils.format("Teacher{name={}, age={}}", this.name, this.age);
}
}
public static void main(String[] args) {
//testReflect();
// testFieldGet();
//testConstructor();
//testInstance();
//testMethod();
testInvoke();
}
static void testInvoke(){
Teacher teacher = new Teacher();
teacher.setName("张三");
teacher.setAge(18);
Console.log("invoke->反射调用方法:",ReflectUtils.invoke(teacher, "toString"));
}
执行结果:
调用了toString
invoke->执行toString结果: Teacher{name=张三, age=0}
八、invokeSetter、invokeGetter
public static void main(String[] args) {
//testReflect();
// testFieldGet();
//testConstructor();
//testInstance();
//testMethod();
//testInvoke();
testGetSet();
}
static void testGetSet(){
Teacher teacher = new Teacher();
Console.log("name->invokeGetter方法执行:");
ReflectUtils.invokeSetter(teacher, "name", "张三");
String name = ReflectUtils.invokeGetter(teacher, "name");
Console.log("name->invokeGetter方法执行:",name);
}
执行结果:
name->invokeGetter方法执行:
name->invokeGetter方法执行: 张三