反射相关的工具类"/>
Java ReflectUtil 反射相关的工具类
静态内部类
/*** 方法类型*/public static class MethodType {/*** 方法类型为 get 方法*/public static String METHOD_TYPE_GET = "get";/*** 方法类型为 set 方法*/public static String METHOD_TYPE_SET = "set";}
判断方法、参数…被标注的所有注解中是否包含某个注解
/*** 判断方法、参数...被标注的所有注解中是否包含某个注解** @param annotations 被标注的所有注解* @param annotation 需要进行判断是否包含的注解* @return true:包含;false:不包含*/public static boolean judgeContainAnnotation(Annotation[] annotations, Annotation annotation) {return Arrays.stream(annotations).anyMatch(annotation1 -> annotation1.annotationType().equals(annotation.annotationType()));}/*** 判断方法、参数...被标注的所有注解中是否包含某个注解** @param annotations 被标注的所有注解* @param annotationClass 需要进行判断是否包含的注解* @return true:包含;false:不包含*/public static boolean judgeContainAnnotation(Annotation[] annotations, Class<? extends Annotation> annotationClass) {return Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().equals(annotationClass));}
获取指定字段的 getter / setter 方法的方法名
/*** 获取指定字段的 getter / setter 方法的方法名** @param methodType 方法类型* @param field 要获取 getter / setter 方法的字段* @return 指定字段的 getter / setter 方法的方法名*/public static String getFieldGetSetMethodName(String methodType, Field field) {// 保证字段能够被访问field.setAccessible(true);// 获取字段名String fieldName = field.getName();// 拼接获取字段对应的方法类型的方法名return methodType + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);}
获取指定字段在指定类中的 getter 方法
/*** 获取指定字段在指定类中的 getter 方法** @param field 字段* @param clazz 类* @return 指定字段在指定类中的 getter 方法*/public static Method getFieldGetMethod(Field field, Class<?> clazz) throws NoSuchMethodException {// 获取字段对应的 getter 方法的方法名String fieldSetMethodName = getFieldGetSetMethodName(MethodType.METHOD_TYPE_GET, field);// 获取字段的类型Class<?> fieldType = field.getType();// 根据方法名和方法参数类型获取指定字段在指定类中的 getter 方法Method fieldGetMethod = clazz.getMethod(fieldSetMethodName, fieldType);// 保证方法可以被访问fieldGetMethod.setAccessible(true);return fieldGetMethod;}
获取指定字段在指定类中的 setter 方法
/*** 获取指定字段在指定类中的 setter 方法** @param field 字段* @param clazz 类* @return 指定字段在指定类中的 setter 方法*/public static Method getFieldSetMethod(Field field, Class<?> clazz) throws NoSuchMethodException {// 获取字段对应的 setter 方法的方法名String fieldSetMethodName = getFieldGetSetMethodName(MethodType.METHOD_TYPE_SET, field);// 获取字段的类型Class<?> fieldType = field.getType();// 根据方法名和方法参数类型获取指定字段在指定类中的 setter 方法Method fieldSetMethod = clazz.getMethod(fieldSetMethodName, fieldType);// 保证方法可以被访问fieldSetMethod.setAccessible(true);return fieldSetMethod;}
获取指定对象的指定字段的值
/*** 获取指定对象的指定字段的值** @param object 对象* @param field 字段* @return 指定字段的值*/public static Object getFieldValue(Object object, Field field) throws IllegalAccessException {// 保证字段可以访问field.setAccessible(true);// 获取并返回指定对象的指定字段的值return field.get(object);}
获取指定对象中的指定字段(不包含父类中的字段)
/*** 获取指定对象中的指定字段(不包含父类中的字段)。* 此方法在获取指定对象中的指定字段时,会包证获取的指定字段能够被访问。** @param object 要获取字段的指定对象* @param fieldName 要获取的指定字段的名称* @return 指定对象中的指定字段*/public static Field getField(Object object, String fieldName) throws NoSuchFieldException {// 获取指定对象的 ClassClass<?> objectClass = object.getClass();// 获取指定对象中的指定字段Field declaredField = objectClass.getDeclaredField(fieldName);// 保证获取的指定字段能够被访问declaredField.setAccessible(true);return declaredField;}
通过反射为字符串对象的 value 字段重新赋值为 strValue
我存在中文乱码问题,
strValueField.set(str, strValue.getBytes(StandardCharsets.UTF_8));
对字符串对象重新赋值后出现乱码,这里我个人不太推荐此方法
/*** 通过反射为字符串对象的 value 字段重新赋值为 strValue,* 从而保证不修改字符串对象的引用,并且能够修改字符串的取值* 由于 JDK 8 中有关反射相关的功能自从 JDK 9 开始就已经被限制了,所以要能够使用运行此方法,* 需要在运行项目时,添加虚拟机(VM)选项:--add-opens java.base/java.lang=ALL-UNNAMED* 开启默认不被允许的行为。* 存在中文乱码问题(待解决)** @param str 需要进行重新赋值的字符串对象* @param strValue 要赋值给字符串对象的值*/public static void setValueString(String str, String strValue) throws NoSuchFieldException, IllegalAccessException {// 获取字符串的 value 字段Field strValueField = getField(str, "value");// 为字符串对象的 value 字段重新赋值strValueField.set(str, strValue.getBytes(StandardCharsets.UTF_8));}
ReflectUtil 完整源码
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;/*** 和反射相关的工具类*/
public class ReflectUtil {/*** 方法类型*/public static class MethodType {/*** 方法类型为 get 方法*/public static String METHOD_TYPE_GET = "get";/*** 方法类型为 set 方法*/public static String METHOD_TYPE_SET = "set";}private ReflectUtil() {}/*** 判断方法、参数...被标注的所有注解中是否包含某个注解** @param annotations 被标注的所有注解* @param annotation 需要进行判断是否包含的注解* @return true:包含;false:不包含*/public static boolean judgeContainAnnotation(Annotation[] annotations, Annotation annotation) {return Arrays.stream(annotations).anyMatch(annotation1 -> annotation1.annotationType().equals(annotation.annotationType()));}/*** 判断方法、参数...被标注的所有注解中是否包含某个注解** @param annotations 被标注的所有注解* @param annotationClass 需要进行判断是否包含的注解* @return true:包含;false:不包含*/public static boolean judgeContainAnnotation(Annotation[] annotations, Class<? extends Annotation> annotationClass) {return Arrays.stream(annotations).anyMatch(annotation -> annotation.annotationType().equals(annotationClass));}/*** 获取指定字段在指定类中的 getter 方法** @param field 字段* @param clazz 类* @return 指定字段在指定类中的 getter 方法*/public static Method getFieldGetMethod(Field field, Class<?> clazz) throws NoSuchMethodException {// 获取字段对应的 getter 方法的方法名String fieldSetMethodName = getFieldGetSetMethodName(MethodType.METHOD_TYPE_GET, field);// 获取字段的类型Class<?> fieldType = field.getType();// 根据方法名和方法参数类型获取指定字段在指定类中的 getter 方法Method fieldGetMethod = clazz.getMethod(fieldSetMethodName, fieldType);// 保证方法可以被访问fieldGetMethod.setAccessible(true);return fieldGetMethod;}/*** 获取指定字段在指定类中的 setter 方法** @param field 字段* @param clazz 类* @return 指定字段在指定类中的 setter 方法*/public static Method getFieldSetMethod(Field field, Class<?> clazz) throws NoSuchMethodException {// 获取字段对应的 setter 方法的方法名String fieldSetMethodName = getFieldGetSetMethodName(MethodType.METHOD_TYPE_SET, field);// 获取字段的类型Class<?> fieldType = field.getType();// 根据方法名和方法参数类型获取指定字段在指定类中的 setter 方法Method fieldSetMethod = clazz.getMethod(fieldSetMethodName, fieldType);// 保证方法可以被访问fieldSetMethod.setAccessible(true);return fieldSetMethod;}/*** 获取指定字段的 getter / setter 方法的方法名** @param methodType 方法类型* @param field 要获取 getter / setter 方法的字段* @return 指定字段的 getter / setter 方法的方法名*/public static String getFieldGetSetMethodName(String methodType, Field field) {// 保证字段能够被访问field.setAccessible(true);// 获取字段名String fieldName = field.getName();// 拼接获取字段对应的方法类型的方法名return methodType + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);}/*** 获取指定对象的指定字段的值** @param object 对象* @param field 字段* @return 指定字段的值*/public static Object getFieldValue(Object object, Field field) throws IllegalAccessException {// 保证字段可以访问field.setAccessible(true);// 获取并返回指定对象的指定字段的值return field.get(object);}/*** 获取指定对象中的指定字段(不包含父类中的字段)。* 此方法在获取指定对象中的指定字段时,会包证获取的指定字段能够被访问。* 由于 JDK 8 中有关反射相关的功能自从 JDK 9 开始就已经被限制了,所以要能够使用运行此方法,* 需要在运行项目时,添加虚拟机(VM)选项:--add-opens java.base/java.lang=ALL-UNNAMED* 开启默认不被允许的行为** @param object 要获取字段的指定对象* @param fieldName 要获取的指定字段的名称* @return 指定对象中的指定字段*/public static Field getField(Object object, String fieldName) throws NoSuchFieldException {// 获取指定对象的 ClassClass<?> objectClass = object.getClass();// 获取指定对象中的指定字段Field declaredField = objectClass.getDeclaredField(fieldName);// 保证获取的指定字段能够被访问declaredField.setAccessible(true);return declaredField;}/*** 通过反射为字符串对象的 value 字段重新赋值为 strValue,* 从而保证不修改字符串对象的引用,并且能够修改字符串的取值* 由于 JDK 8 中有关反射相关的功能自从 JDK 9 开始就已经被限制了,所以要能够使用运行此方法,* 需要在运行项目时,添加虚拟机(VM)选项:--add-opens java.base/java.lang=ALL-UNNAMED* 开启默认不被允许的行为。* 存在中文乱码问题(待解决)** @param str 需要进行重新赋值的字符串对象* @param strValue 要赋值给字符串对象的值*/public static void setValueString(String str, String strValue) throws NoSuchFieldException, IllegalAccessException {// 获取字符串的 value 字段Field strValueField = getField(str, "value");// 为字符串对象的 value 字段重新赋值strValueField.set(str, strValue.getBytes(StandardCharsets.UTF_8));}}
更多推荐
Java ReflectUtil 反射相关的工具类
发布评论