diff --git a/CHANGELOG.md b/CHANGELOG.md index 135058b4c..5a2576ade 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ ## 5.2.5 ### 新特性 +* 【core 】 增加逻辑,对于原始类型注入,(issue#797@Github) + ### Bug修复 ------------------------------------------------------------------------------------------------------------- diff --git a/bin/install.sh b/bin/install.sh index cc34f01db..2797ca7e1 100755 --- a/bin/install.sh +++ b/bin/install.sh @@ -1,3 +1,3 @@ #!/bin/bash -exec mvn clean source:jar javadoc:javadoc install -Dmaven.test.skip=false -Dmaven.javadoc.skip=false +exec mvn -T 1C clean source:jar javadoc:javadoc install -Dmaven.test.skip=false -Dmaven.javadoc.skip=false diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java index 71b7b17b9..773aca748 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java @@ -11,7 +11,6 @@ import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -import java.lang.reflect.AccessibleObject; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.util.HashMap; @@ -67,7 +66,7 @@ public class AnnotationUtil { * 如果无指定的属性方法返回null * * @param 注解值类型 - * @param annotationEle {@link AccessibleObject},可以是Class、Method、Field、Constructor、ReflectPermission + * @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission * @param annotationType 注解类型 * @return 注解对象 * @throws UtilException 调用注解中的方法时执行异常 @@ -81,7 +80,7 @@ public class AnnotationUtil { * 如果无指定的属性方法返回null * * @param 注解值类型 - * @param annotationEle {@link AccessibleObject},可以是Class、Method、Field、Constructor、ReflectPermission + * @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission * @param annotationType 注解类型 * @param propertyName 属性名,例如注解中定义了name()方法,则 此处传入name * @return 注解对象 diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java b/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java index ffc561205..80fea3fd4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/copier/BeanCopier.java @@ -283,7 +283,7 @@ public class BeanCopier implements Copier, Serializable { ReflectUtil.setFieldValue(bean, field, value); } else{ // 执行set方法注入值 - setterMethod.invoke(bean, value); + ReflectUtil.invoke(bean, setterMethod, value); } } catch (Exception e) { if (false ==copyOptions.ignoreError) { diff --git a/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java index 98e25dd9b..f805ff586 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java @@ -304,7 +304,7 @@ public class ReflectUtil { Assert.notNull(obj); Assert.notBlank(fieldName); - final Field field = getField((obj instanceof Class) ? (Class)obj : obj.getClass(), fieldName); + final Field field = getField((obj instanceof Class) ? (Class) obj : obj.getClass(), fieldName); Assert.notNull(field, "Field [{}] is not exist in [{}]", fieldName, obj.getClass().getName()); setFieldValue(obj, field, value); } @@ -320,8 +320,8 @@ public class ReflectUtil { public static void setFieldValue(Object obj, Field field, Object value) throws UtilException { Assert.notNull(field, "Field in [{}] not exist !", obj); + final Class fieldType = field.getType(); if (null != value) { - Class fieldType = field.getType(); if (false == fieldType.isAssignableFrom(value.getClass())) { //对于类型不同的字段,尝试转换,转换失败则使用原对象类型 final Object targetValue = Convert.convert(fieldType, value); @@ -329,6 +329,9 @@ public class ReflectUtil { value = targetValue; } } + } else { + // 获取null对应默认值,防止原始类型造成空指针问题 + value = ClassUtil.getDefaultValue(fieldType); } setAccessible(field); @@ -848,6 +851,15 @@ public class ReflectUtil { /** * 执行方法 * + *

+ * 对于用户传入参数会做必要检查,包括: + * + *

+	 *     1、忽略多余的参数
+	 *     2、参数不够补齐默认值
+	 *     3、传入参数为null,但是目标参数类型为原始类型,做转换
+	 * 
+ * * @param 返回对象类型 * @param obj 对象,如果执行静态方法,此值为null * @param method 方法(对象方法或static方法都可) @@ -859,8 +871,32 @@ public class ReflectUtil { public static T invoke(Object obj, Method method, Object... args) throws UtilException { setAccessible(method); + // 检查用户传入参数: + // 1、忽略多余的参数 + // 2、参数不够补齐默认值 + // 3、传入参数为null,但是目标参数类型为原始类型,做转换 + // 4、传入参数类型不对应,尝试转换类型 + 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 (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]; + } + } + } + try { - return (T) method.invoke(ClassUtil.isStatic(method) ? null : obj, args); + return (T) method.invoke(ClassUtil.isStatic(method) ? null : obj, actualArgs); } catch (Exception e) { throw new UtilException(e); } diff --git a/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java index 1c8676a20..71ceafb5e 100644 --- a/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/bean/BeanUtilTest.java @@ -321,9 +321,9 @@ public class BeanUtilTest { @Test public void beanToBeanTest(){ - // 复现对象无getter方法导致报错的问题 + // 修复对象无getter方法导致报错的问题 Page page1=new Page(); - BeanUtil.toBean(page1, Page.class, CopyOptions.create().setIgnoreNullValue(true)); + BeanUtil.toBean(page1, Page.class); } public static class Page {