反射是 Java 中一种强大的机制,可以在运行时动态地获取类的信息并操作类的属性和方法。在 Java 中,通过反射可以获取和设置类的字段、调用类的方法、创建类的实例等。Java的反射机制,可以让语言变得更加灵活,对对象的操作也更加“动态”,因此在某些情况下,反射可以做到事半功倍的效果。本文将介绍如何使用Hutool中的反射工具类来获取获取类信息、操作字段、调用方法、构造对象等常见功能,并提供了相关的代码示例。
Hutool是一个Java工具类库,提供了很多常用的工具类和方法,包括反射操作。通过Hutool,我们可以更加方便地使用反射来获取类的属性值。Hutool针对Java的反射机制做了工具化封装,封装包括获取构造方法、获取字段、获取字段值、获取方法、执行方法(对象方法和静态方法)等。示例如下所示:
// 获取某个类的所有方法
Method[] methods = ReflectUtil.getMethods(PmsBrand.class);
// 获取某个类的指定方法
Method method = ReflectUtil.getMethod(PmsBrand.class, "getId");
// 使用反射来创建对象
PmsBrand pmsBrand = ReflectUtil.newInstance(PmsBrand.class);
// 反射执行对象的方法
ReflectUtil.invoke(pmsBrand,"setId",1);
return CommonResult.success(null,"操作成功!");
在使用Hutool工具之前,我们需要将Hutool添加到项目的依赖中。如果使用Maven构建项目,可以在 pom.xml 文件中添加以下依赖:
<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
Hutool-all 是一个 Hutool 的集成打包产品,由于考虑到“懒人”用户及分不清各个模块作用的用户,“无脑”引入 hutool-all 模块是快速开始和深入应用的最佳方式。如果你想像 SpringBoot 一样引入 Hutool,再由子模块决定用到哪些模块,你可以在父模块中加入:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-bom</artifactId>
<version>${hutool.version}</version>
<type>pom</type>
<!-- 注意这里是import -->
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后再在子模块中就可以引入自己需要的模块了:
<dependencies>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-core</artifactId>
</dependency>
</dependencies>
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private Integer age;
private Boolean gender;
}
工具类通常由静态方法组成,并且构造函数设为私有以防止实例化,如下所示。
public class ReflectUtil {
// 私有构造函数,防止实例化
public ReflectUtil() {
}
}
ReflectionUtil 是一个Java反射工具类,它提供了一些简化反射操作的方法。ReflectionUtil 可以获取类的各种信息,比如类名、类的修饰符、类的父类、实现的接口等,这些信息可以通过调用 ReflectionUtil 的方法来获取。
通过反射创建对象,包括使用无参和有参构造方法,如下所示。
@Test
public void constructorTest() {
// 获取所有构造方法
Constructor<User>[] constructors = ReflectUtil.getConstructors(User.class);
for (Constructor<User> constructor : constructors) {
Console.log("getConstructors->获取构造方法:", constructor);
}
// 获取无参构造方法
Constructor<User> constructor = ReflectUtil.getConstructor(User.class);
Console.log("getConstructor->获取无参构造方法:", constructor);
// 获取有参构造方法
Constructor<User> constructor1 = ReflectUtil.getConstructor(User.class, String.class, Integer.class,Boolean.class);
Console.log("getConstructor->获取有参构造方法:", constructor1);
String name = constructor1.getName();
Console.log("name:{}", name);
int modifiers = constructor1.getModifiers();
Console.log("modifiers:{}", modifiers);
}
ReflectionUtil 可以通过反射来创建对象,它提供了一个newInstance 方法,可以根据类名来创建相应的对象。
@Test
public void newInstanceTest() {
ReflectUtil.newInstance(User.class);
}
通过反射调用类的方法,包括获取方法和执行方法,ReflectionUtil 同样提供了方法来简化方法的调用,一些儿常用方法如下所示。
// 查找指定方法。如果找不到对应的方法则返回null
Method getMethod(Class<?> clazz, boolean ignoreCase, String methodName, Class<?>... paramTypes);
// 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回null
Method getMethodIgnoreCase(Class<?> clazz, String methodName, Class<?>... paramTypes);
// 查找指定方法。如果找不到对应的方法则返回null
Method getMethodByName(Class<?> clazz, boolean ignoreCase, String methodName);
// 获得指定类中的方法名
Method[] getMethods(Class<?> beanClass);
// 调用方法。
T invoke(Object obj, Method method, Object... args) throws InvocationTargetRuntimeException, UtilException;
// 执行方法
T invoke(Object obj, String methodName, Object... args) throws UtilException;
T invokeRaw(Object obj, Method method, Object... args) throws InvocationTargetException, IllegalAccessException;
// 执行静态方法
T invokeStatic(Method method, Object... args) throws UtilException;
// 执行方法,执行前要检查给定参数
T invokeWithCheck(Object obj, Method method, Object... args) throws UtilException;
/**
* 获取某个类的所有方法
*/
@Test
public void getMethodsTest() {
Method[] methods = ReflectUtil.getMethods(User.class);
Arrays.stream(methods).forEach(System.out::println);
}
/**
* 获取某个类的指定方法
*/
@Test
public void getMethodTest() {
Method methods = ReflectUtil.getMethod(User.class, "getName");
}
ReflectionUtil 可以通过反射来调用类的方法,它提供了 invokeXXXX
方法,可以根据方法名和参数类型来调用相应的方法。
@Test
public void invokeMethodTest() {
ReflectUtil.invoke(User.class, "setName", "独泪了无痕");
}
ReflectUtil 也简化了对字段的访问操作,可以通过反射来获取对象的字段值,它提供了一个 getFieldValue
方法,可以根据字段名来获取相应的字段值。除此之外,还可以通过反射来设置对象的字段值,提供了一个 setFieldValue
方法,可以根据字段名来设置相应的字段值。
// 查找指定类中的指定name的字段,也包括父类和Object类的字段,字段不存在则返回null
Field getField(Class<?> beanClass, String name);
// 获取指定类中字段名和字段对应的有序Map,包括其父类中的字段。
// 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后
Map<String, Field> getFieldMap(Class<?> beanClass);
// 获取字段名,如果存在Alias注解,读取注解的值作为名称
String getFieldName(Field field);
// 获得一个类中所有字段列表,包括其父类中的字段。
// 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后
Field[] getFields(Class<?> beanClass);
// 获取指定对象所有字段的值
Object[] getFieldsValue(Object obj);
// 获取字段值
Object getFieldValue(Object obj, Field field);
Object getFieldValue(Object obj, String fieldName);
@Test
public void getFieldsTest() {
User user = new User();
// 获取实体中所有属性字段
Field[] fields = ReflectUtil.getFields(user.getClass());
Arrays.stream(fields).forEach(field -> {
Console.log("getFields-获取User类的所有字段:", field);
Console.log("getFieldName->获取字段名:", ReflectUtil.getFieldName(field));
Console.log("getFieldValue->获取字段值:", ReflectUtil.getFieldValue(new User(), field));
Console.log("getModifiers->获取字段修饰符:", field.getModifiers());
Console.log("getType->获取字段类型:", field.getType());
Console.log("获取属性字段类型:", field.getType().getCanonicalName());
});
}
通过 Hutool 中的 ReflectUtil 类,我们可以获取Java类的字段值,如下所示:
@Test
public void getFieldValueTest() {
User user = new User();
user.setName("独泪了无痕");
user.setAge(30);
user.setGender(true);
System.out.println("Name:" + ReflectUtil.getFieldValue(user, "name"));
System.out.println("Age:" + ReflectUtil.getFieldValue(user, "age"));
System.out.println("Gender:" + ReflectUtil.getFieldValue(user, "gender"));
}
在上面的示例中,我们通过 ReflectUtil.getFieldValue()
方法获取了类的字段值。该方法接受两个参数,第一个参数是要获取字段值的对象,第二个参数是字段的名称。
ReflectUtils类通过结合Java反射和Lambda表达式,提供了一种简洁高效的方式来操作对象的字段。它不仅提高了代码的可读性,还通过缓存机制优化了性能。掌握这个工具类的使用,将有助于提升Java开发的灵活性和效率。但使用反射仍然需要谨慎。反射操作可能会破坏封装性、增加性能开销,并可能引发安全问题。因此,在不需要动态访问的情况下,最好避免使用反射。
Hotool 不仅仅只有这一种工具类,还包含了其他许多工具类。在这里我作为一名Hutool的用户,我感谢Hutool的创作者和维护者们为我们带来如此强大便捷的工具库,希望Hutool功能越来越完善,为我们的开发工作带来更多的便利。同时也祝愿所有开发者没有BUG困扰,能够愉快地编写出高效、功能完善的程序。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ovod.cn 版权所有 湘ICP备2023023988号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务