Search in sources :

Example 1 with NullWrapperBean

use of cn.hutool.core.bean.NullWrapperBean in project hutool by looly.

the class ReflectUtil method invoke.

/**
 * 执行方法
 *
 * <p>
 * 对于用户传入参数会做必要检查,包括:
 *
 * <pre>
 *     1、忽略多余的参数
 *     2、参数不够补齐默认值
 *     3、传入参数为null,但是目标参数类型为原始类型,做转换
 * </pre>
 *
 * @param <T>    返回对象类型
 * @param obj    对象,如果执行静态方法,此值为{@code null}
 * @param method 方法(对象方法或static方法都可)
 * @param args   参数对象
 * @return 结果
 * @throws UtilException 一些列异常的包装
 */
@SuppressWarnings("unchecked")
public static <T> T invoke(Object obj, Method method, Object... args) throws UtilException {
    setAccessible(method);
    // 检查用户传入参数:
    // 1、忽略多余的参数
    // 2、参数不够补齐默认值
    // 3、通过NullWrapperBean传递的参数,会直接赋值null
    // 4、传入参数为null,但是目标参数类型为原始类型,做转换
    // 5、传入参数类型不对应,尝试转换类型
    final Class<?>[] parameterTypes = method.getParameterTypes();
    final Object[] actualArgs = new Object[parameterTypes.length];
    if (null != args) {
        for (int i = 0; i < actualArgs.length; i++) {
            if (i >= args.length || null == args[i]) {
                // 越界或者空值
                actualArgs[i] = ClassUtil.getDefaultValue(parameterTypes[i]);
            } else if (args[i] instanceof NullWrapperBean) {
                // 如果是通过NullWrapperBean传递的null参数,直接赋值null
                actualArgs[i] = null;
            } else if (false == parameterTypes[i].isAssignableFrom(args[i].getClass())) {
                // 对于类型不同的字段,尝试转换,转换失败则使用原对象类型
                final Object targetValue = Convert.convert(parameterTypes[i], args[i]);
                if (null != targetValue) {
                    actualArgs[i] = targetValue;
                }
            } else {
                actualArgs[i] = args[i];
            }
        }
    }
    if (method.isDefault()) {
        // 代理对象情况下调用method.invoke会导致循环引用执行,最终栈溢出
        return MethodHandleUtil.invokeSpecial(obj, method, args);
    }
    try {
        return (T) method.invoke(ClassUtil.isStatic(method) ? null : obj, actualArgs);
    } catch (Exception e) {
        throw new UtilException(e);
    }
}
Also used : NullWrapperBean(cn.hutool.core.bean.NullWrapperBean) UtilException(cn.hutool.core.exceptions.UtilException) AccessibleObject(java.lang.reflect.AccessibleObject) UtilException(cn.hutool.core.exceptions.UtilException)

Aggregations

NullWrapperBean (cn.hutool.core.bean.NullWrapperBean)1 UtilException (cn.hutool.core.exceptions.UtilException)1 AccessibleObject (java.lang.reflect.AccessibleObject)1