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);
}
}
Aggregations