反射详解一

  • 反射能干什么

  •  得到 Class 的三种方式
  Person p1 = new Person();
  Class c1 = p1.getClass();

  Class c2 = Person.class;

  Class c3 = Class.forName("com.ys.reflex.Person");
  • 通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等
复制代码
  查阅 API 可以看到 Class 有很多方法:

  getName():获得类的完整名字。
  getFields():获得类的public类型的属性。
  getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
  getMethods():获得类的public类型的方法。
  getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
  getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
  getConstructors():获得类的public类型的构造方法。
  getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
  newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
复制代码
  • 工具类
复制代码
public class ReflectUtils extends ReflectionUtils {

    /**
     * 获取类属性(包含私有以及受保护的,父类也会检索)
     *
     * @param sourceClass 类
     * @param fieldName   属性名称
     * @return 属性
     */
    public static Field getField(Class<?> sourceClass, String fieldName) {
        Field field = null;
        try {
            field = sourceClass.getField(fieldName);
        } catch (NoSuchFieldException ignored) {

        }

        if (field == null) {
            try {
                field = sourceClass.getDeclaredField(fieldName);
            } catch (NoSuchFieldException ignored) {

            }
        }

        if (field == null) {
            Class<?> superClass = sourceClass.getSuperclass();
            if (superClass != null) {
                field = getField(superClass, fieldName);
            }
        }
        return field;
    }

    /**
     * 获取属性的值
     *
     * @param object    对象
     * @param fieldName 属性名
     * @return 属性值
     */
    public static Object getFieldValue(Object object, String fieldName) {
        Object value = null;
        if (object != null) {
            Field field = getField(object.getClass(), fieldName);
            if (field != null) {
                field.setAccessible(true);
                try {
                    value = field.get(object);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            } else {
                System.err.println("Field is not exist");
            }
        }
        return value;
    }

    /**
     * 获取静态属性值
     *
     * @param sourceClass 类
     * @param fieldName   属性名
     * @return 属性值
     */
    public static Object getStaticFieldValue(Class<?> sourceClass, String fieldName) {
        Field field = getField(sourceClass, fieldName);
        Object value = null;
        if (field != null) {
            field.setAccessible(true);
            if (isStatic(field)) {
                try {
                    value = field.get(null);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            } else {
                System.err.println("Field is not static");
            }
        } else {
            System.err.println("Field is not exist");
        }
        return value;
    }

    /**
     * 设置属性值
     *
     * @param object    对象
     * @param fieldName 属性名
     * @param newValue  新值
     */
    public static void setFieldValue(Object object, String fieldName, Object newValue) {
        if (object != null) {
            Field field = getField(object.getClass(), fieldName);
            if (field != null) {
                field.setAccessible(true);
                if (!isFinal(field)) {
                    try {
                        field.set(object, newValue);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.err.println("Field is final");
                }
            } else {
                System.err.println("Field is not exist");
            }
        }
    }

    /**
     * 设置静态属性值
     *
     * @param sourceClass 类
     * @param fieldName   属性名
     * @param newValue    新值
     */
    public static void setStaticFieldValue(Class<?> sourceClass, String fieldName, Object newValue) {
        Field field = getField(sourceClass, fieldName);
        if (field != null) {
            field.setAccessible(true);
            if (isStatic(field)) {
                if (!isFinal(field)) {
                    try {
                        field.set(null, newValue);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                } else {
                    System.err.println("Field is final");
                }
            } else {
                System.err.println("Field is not static");
            }
        } else {
            System.err.println("Field is not exist");
        }
    }

    /**
     * 是否静态(方法、属性。。。)
     *
     * @param field 要判断的对象
     * @return 是否
     */
    public static boolean isStatic(Object field) {
        return java.lang.reflect.Modifier.isStatic((Integer) invokeMethod(field, "getModifiers", null));
    }

    /**
     * 是否不可变/覆写(方法、属性。。。)
     *
     * @param field 要判断的对象
     * @return 是否
     */
    public static boolean isFinal(Object field) {
        return java.lang.reflect.Modifier.isFinal((Integer) invokeMethod(field, "getModifiers", null));
    }

    /**
     * 是否公共(方法、属性。。。)
     *
     * @param field 要判断的对象
     * @return 是否
     */
    public static boolean isPublic(Object field) {
        return java.lang.reflect.Modifier.isPublic((Integer) invokeMethod(field, "getModifiers", null));
    }

    /**
     * 是否私有(方法、属性。。。)
     *
     * @param field 要判断的对象
     * @return 是否
     */
    public static boolean isPrivate(Object field) {
        return java.lang.reflect.Modifier.isPrivate((Integer) invokeMethod(field, "getModifiers", null));
    }

    /**
     * 是否受保护(方法、属性。。。)
     *
     * @param field 要判断的对象
     * @return 是否
     */
    public static boolean isProtected(Object field) {
        return java.lang.reflect.Modifier.isProtected((Integer) invokeMethod(field, "getModifiers", null));
    }


    /**
     * 获取类方法(包含私有以及受保护的,父类也会检索)
     *
     * @param sourceClass 类
     * @param methodName  方法名
     * @param var2        方法的参数类型
     * @return 方法对象
     */
    public static Method getMethod(Class<?> sourceClass, String methodName, Class... var2) {
        Method method = null;
        try {
            method = sourceClass.getMethod(methodName, var2);
        } catch (NoSuchMethodException ignored) {

        }

        if (method == null) {
            try {
                method = sourceClass.getDeclaredMethod(methodName, var2);
            } catch (NoSuchMethodException ignored) {

            }
        }

        if (method == null) {
            Class<?> superClass = sourceClass.getSuperclass();
            if (superClass != null) {
                method = getMethod(superClass, methodName, var2);
            }
        }
        return method;
    }

    /**
     * 执行静态方法
     *
     * @param sourceClass 类
     * @param methodName  方法名
     * @param var2        参数
     * @return 执行结果
     */
    public static Object invokeStaticMethod(Class<?> sourceClass, String methodName, Object... var2) {
        Class<?>[] args = null;
        if (var2 != null) {
            args = new Class[var2.length];
            for (int i = 0; i < var2.length; i++) {
                args[i] = var2[i].getClass();
            }
        }
        Method method = getMethod(sourceClass, methodName, args);
        Object result = null;
        try {
            if (method != null) {
                if (isStatic(method)) {
                    method.setAccessible(true);
                    result = method.invoke(null, var2);
                } else {
                    System.err.println("method is not static");
                }
            } else {
                System.err.println("Method is not exist");
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 执行类方法
     *
     * @param sourceObject 类对象
     * @param methodName   方法名
     * @param var2         参数
     * @return 执行结果
     */
    public static Object invokeMethod(Object sourceObject, String methodName, Object... var2) {
        Class<?>[] args = null;
        if (var2 != null) {
            args = new Class[var2.length];
            for (int i = 0; i < var2.length; i++) {
                args[i] = var2[i].getClass();
            }
        }
        Method method = getMethod(sourceObject.getClass(), methodName, args);
        Object result = null;
        try {
            if (method != null) {
                method.setAccessible(true);
                result = method.invoke(sourceObject, var2);
            } else {
                System.err.println("Method is not exist");
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return result;
    }
}
View Code
复制代码
  •  自定义注解
@Target(FIELD)
@Retention(RUNTIME)
@Documented
public @interface DataVerify {
     boolean nullable() default true;//是否允许为空
     String regex() default "";//校验正则

}
@DataVerify(nullable = false)
private String updateTime;
  • 反射实例
复制代码
  public static  Object trimData(Object model) {
        try {
            Field fields[] = model.getClass().getDeclaredFields();
            for (Field field : fields) {
                Object valueObj = ReflectUtil.getFieldValue(model,field);
                String value = valueObj == null ? "" : valueObj.toString().trim(); // 这个对象字段get方法的值
                String fieldName = field.getName();
                if("createTime".equals(fieldName)||"updateTime".equals(fieldName)){
                    value=DateUtils.formatDate2Noformat(value);
                }
                ReflectUtil.setFieldValue(model, field, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return model;
    }
复制代码

 

复制代码
  public static  Object cleanDataService(Object model) {
        try {
            model=trimData(model);
            Field fields[] = model.getClass().getDeclaredFields();
            for (Field field : fields) {
                DataVerify action = field.getAnnotation(DataVerify.class);
                if (action == null || (StrUtil.isEmpty(action.regex()) && action.nullable())) {
                    continue;
                }
                String knameMethod = field.getName().substring(0, 1).toUpperCase()
                        + field.getName().substring(1); // 将属性的首字符大写,方便构造get,set方法
                Method m = model.getClass().getMethod("get" + knameMethod);
                Object valueObj = m.invoke(model, new Object[]{});
                String value = valueObj == null ? "" : valueObj.toString(); // 这个对象字段get方法的值
                if (!action.nullable() && StrUtil.isEmpty(value)) {
                    m = model.getClass().getMethod("setNeedClean", String.class);
                    m.invoke(model, "1");
                    m = model.getClass().getMethod("setCleanDesc", String.class);
                    m.invoke(model, "字段[" + field.getName() + "] 不能为空");
                    return model;
                }
                if (StrUtil.isNotEmpty(action.regex())) {
                    if (action.nullable() && StrUtil.isEmpty(value)) {
                        continue;
                    } else if (!ReUtil.isMatch(action.regex(), value)) {
                        m = model.getClass().getMethod("setNeedClean", String.class);
                        m.invoke(model, "1");
                        m = model.getClass().getMethod("setCleanDesc", String.class);
                        m.invoke(model, "字段[" + field.getName() + "] 格式不正确,校验正则:" + action.regex());
                    }
                    return model;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        return model;
    }
复制代码

 

posted @   Bonnie_ξ  阅读(62)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示