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 884e98173..a7c33e5f3 100755 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java @@ -1,9 +1,9 @@ package cn.hutool.core.annotation; import cn.hutool.core.exceptions.UtilException; +import cn.hutool.core.reflect.FieldUtil; import cn.hutool.core.reflect.MethodUtil; import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.reflect.ReflectUtil; import java.lang.annotation.Annotation; import java.lang.annotation.Documented; @@ -277,7 +277,7 @@ public class AnnotationUtil { */ @SuppressWarnings({"rawtypes", "unchecked"}) public static void setValue(final Annotation annotation, final String annotationField, final Object value) { - final Map memberValues = (Map) ReflectUtil.getFieldValue(Proxy.getInvocationHandler(annotation), "memberValues"); + final Map memberValues = (Map) FieldUtil.getFieldValue(Proxy.getInvocationHandler(annotation), "memberValues"); memberValues.put(annotationField, value); } diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/BeanDesc.java b/hutool-core/src/main/java/cn/hutool/core/bean/BeanDesc.java index 161f27abd..031b311a4 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/BeanDesc.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/BeanDesc.java @@ -2,11 +2,11 @@ package cn.hutool.core.bean; import cn.hutool.core.lang.Assert; import cn.hutool.core.map.CaseInsensitiveMap; +import cn.hutool.core.reflect.FieldUtil; import cn.hutool.core.reflect.MethodUtil; -import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.reflect.ModifierUtil; -import cn.hutool.core.reflect.ReflectUtil; import cn.hutool.core.text.StrUtil; +import cn.hutool.core.util.BooleanUtil; import java.io.Serializable; import java.lang.reflect.Field; @@ -143,9 +143,9 @@ public class BeanDesc implements Serializable { private BeanDesc init() { final Method[] gettersAndSetters = MethodUtil.getMethods(this.beanClass, MethodUtil::isGetterOrSetterIgnoreCase); PropDesc prop; - for (final Field field : ReflectUtil.getFields(this.beanClass)) { + for (final Field field : FieldUtil.getFields(this.beanClass)) { // 排除静态属性和对象子类 - if (false == ModifierUtil.isStatic(field) && false == ReflectUtil.isOuterClassField(field)) { + if (false == ModifierUtil.isStatic(field) && false == FieldUtil.isOuterClassField(field)) { prop = createProp(field, gettersAndSetters); // 只有不存在时才放入,防止父类属性覆盖子类属性 this.propMap.putIfAbsent(prop.getFieldName(), prop); diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java b/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java index 945b09118..4061bd276 100755 --- a/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/BeanUtil.java @@ -8,12 +8,13 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.func.Editor; import cn.hutool.core.map.CaseInsensitiveMap; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.reflect.ClassUtil; +import cn.hutool.core.reflect.ConstructorUtil; +import cn.hutool.core.reflect.FieldUtil; import cn.hutool.core.reflect.ModifierUtil; -import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.reflect.ReflectUtil; import cn.hutool.core.text.StrUtil; +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ObjUtil; import java.beans.BeanInfo; import java.beans.IntrospectionException; @@ -298,7 +299,7 @@ public class BeanUtil { return ArrayUtil.map(bean, Object.class, (beanEle) -> getFieldValue(beanEle, fieldNameOrIndex)); } } else {// 普通Bean对象 - return ReflectUtil.getFieldValue(bean, fieldNameOrIndex); + return FieldUtil.getFieldValue(bean, fieldNameOrIndex); } } @@ -320,7 +321,7 @@ public class BeanUtil { ArrayUtil.setOrAppend(bean, Convert.toInt(fieldNameOrIndex), value); } else { // 普通Bean对象 - ReflectUtil.setFieldValue(bean, fieldNameOrIndex, value); + FieldUtil.setFieldValue(bean, fieldNameOrIndex, value); } } @@ -368,7 +369,7 @@ public class BeanUtil { * @return Bean */ public static T mapToBean(final Map map, final Class beanClass, final boolean isToCamelCase, final CopyOptions copyOptions) { - return fillBeanWithMap(map, ReflectUtil.newInstanceIfPossible(beanClass), isToCamelCase, copyOptions); + return fillBeanWithMap(map, ConstructorUtil.newInstanceIfPossible(beanClass), isToCamelCase, copyOptions); } // --------------------------------------------------------------------------------------------- fillBeanWithMap @@ -504,7 +505,7 @@ public class BeanUtil { * @since 5.2.4 */ public static T toBean(final Object source, final Class clazz, final CopyOptions options) { - return toBean(source, () -> ReflectUtil.newInstanceIfPossible(clazz), options); + return toBean(source, () -> ConstructorUtil.newInstanceIfPossible(clazz), options); } /** @@ -539,7 +540,7 @@ public class BeanUtil { if (null == beanClass || null == valueProvider) { return null; } - return fillBean(ReflectUtil.newInstanceIfPossible(beanClass), valueProvider, copyOptions); + return fillBean(ConstructorUtil.newInstanceIfPossible(beanClass), valueProvider, copyOptions); } /** @@ -681,7 +682,7 @@ public class BeanUtil { * @return 目标对象 */ public static T copyProperties(final Object source, final Class tClass, final String... ignoreProperties) { - final T target = ReflectUtil.newInstanceIfPossible(tClass); + final T target = ConstructorUtil.newInstanceIfPossible(tClass); copyProperties(source, target, CopyOptions.create().setIgnoreProperties(ignoreProperties)); return target; } @@ -740,7 +741,7 @@ public class BeanUtil { return new ArrayList<>(0); } return collection.stream().map((source) -> { - final T target = ReflectUtil.newInstanceIfPossible(targetType); + final T target = ConstructorUtil.newInstanceIfPossible(targetType); copyProperties(source, target, copyOptions); return target; }).collect(Collectors.toList()); @@ -793,7 +794,7 @@ public class BeanUtil { return null; } - final Field[] fields = ReflectUtil.getFields(bean.getClass()); + final Field[] fields = FieldUtil.getFields(bean.getClass()); for (final Field field : fields) { if (ModifierUtil.isStatic(field)) { continue; @@ -821,12 +822,12 @@ public class BeanUtil { } if (String.class.equals(field.getType())) { // 只有String的Field才处理 - final String val = (String) ReflectUtil.getFieldValue(bean, field); + final String val = (String) FieldUtil.getFieldValue(bean, field); if (null != val) { final String trimVal = StrUtil.trim(val); if (false == val.equals(trimVal)) { // Field Value不为null,且首尾有空格才处理 - ReflectUtil.setFieldValue(bean, field, trimVal); + FieldUtil.setFieldValue(bean, field, trimVal); } } } @@ -857,12 +858,12 @@ public class BeanUtil { */ public static boolean isEmpty(final Object bean, final String... ignoreFiledNames) { if (null != bean) { - for (final Field field : ReflectUtil.getFields(bean.getClass())) { + for (final Field field : FieldUtil.getFields(bean.getClass())) { if (ModifierUtil.isStatic(field)) { continue; } if ((false == ArrayUtil.contains(ignoreFiledNames, field.getName())) - && null != ReflectUtil.getFieldValue(bean, field)) { + && null != FieldUtil.getFieldValue(bean, field)) { return false; } } @@ -883,12 +884,12 @@ public class BeanUtil { if (null == bean) { return true; } - for (final Field field : ReflectUtil.getFields(bean.getClass())) { + for (final Field field : FieldUtil.getFields(bean.getClass())) { if (ModifierUtil.isStatic(field)) { continue; } if ((false == ArrayUtil.contains(ignoreFiledNames, field.getName())) - && null == ReflectUtil.getFieldValue(bean, field)) { + && null == FieldUtil.getFieldValue(bean, field)) { return true; } } diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/DynaBean.java b/hutool-core/src/main/java/cn/hutool/core/bean/DynaBean.java index 8a8991b58..2c755e532 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/DynaBean.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/DynaBean.java @@ -3,8 +3,8 @@ package cn.hutool.core.bean; import cn.hutool.core.clone.CloneSupport; import cn.hutool.core.lang.Assert; import cn.hutool.core.reflect.ClassUtil; +import cn.hutool.core.reflect.ConstructorUtil; import cn.hutool.core.reflect.MethodUtil; -import cn.hutool.core.reflect.ReflectUtil; import java.io.Serializable; import java.util.Map; @@ -63,7 +63,7 @@ public class DynaBean extends CloneSupport implements Serializable { * @param params 构造Bean所需要的参数 */ public DynaBean(final Class beanClass, final Object... params) { - this(ReflectUtil.newInstance(beanClass, params)); + this(ConstructorUtil.newInstance(beanClass, params)); } /** @@ -72,7 +72,7 @@ public class DynaBean extends CloneSupport implements Serializable { * @param beanClass Bean类 */ public DynaBean(final Class beanClass) { - this(ReflectUtil.newInstance(beanClass)); + this(ConstructorUtil.newInstance(beanClass)); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/bean/PropDesc.java b/hutool-core/src/main/java/cn/hutool/core/bean/PropDesc.java index f320e2c12..5946eaab1 100644 --- a/hutool-core/src/main/java/cn/hutool/core/bean/PropDesc.java +++ b/hutool-core/src/main/java/cn/hutool/core/bean/PropDesc.java @@ -3,6 +3,7 @@ package cn.hutool.core.bean; import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.annotation.PropIgnore; import cn.hutool.core.convert.Convert; +import cn.hutool.core.reflect.FieldUtil; import cn.hutool.core.reflect.MethodUtil; import cn.hutool.core.reflect.ModifierUtil; import cn.hutool.core.reflect.ReflectUtil; @@ -53,7 +54,7 @@ public class PropDesc { * @return 字段名 */ public String getFieldName() { - return ReflectUtil.getFieldName(this.field); + return FieldUtil.getFieldName(this.field); } /** @@ -154,7 +155,7 @@ public class PropDesc { if (null != this.getter) { return MethodUtil.invoke(bean, this.getter); } else if (ModifierUtil.isPublic(this.field)) { - return ReflectUtil.getFieldValue(bean, this.field); + return FieldUtil.getFieldValue(bean, this.field); } return null; @@ -225,7 +226,7 @@ public class PropDesc { if (null != this.setter) { MethodUtil.invoke(bean, this.setter, value); } else if (ModifierUtil.isPublic(this.field)) { - ReflectUtil.setFieldValue(bean, this.field, value); + FieldUtil.setFieldValue(bean, this.field, value); } return this; } diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java index e99554557..b979ede0d 100755 --- a/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/CollUtil.java @@ -17,13 +17,14 @@ import cn.hutool.core.lang.func.Func1; import cn.hutool.core.lang.func.Matcher; import cn.hutool.core.lang.hash.Hash32; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.reflect.ClassUtil; +import cn.hutool.core.reflect.ConstructorUtil; +import cn.hutool.core.reflect.FieldUtil; +import cn.hutool.core.reflect.TypeUtil; +import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.CharUtil; -import cn.hutool.core.reflect.ClassUtil; import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.reflect.ReflectUtil; -import cn.hutool.core.text.StrUtil; -import cn.hutool.core.reflect.TypeUtil; import java.io.Serializable; import java.lang.reflect.Type; @@ -1010,7 +1011,7 @@ public class CollUtil { // Others,直接实例化 else { try { - list = (Collection) ReflectUtil.newInstance(collectionType); + list = (Collection) ConstructorUtil.newInstance(collectionType); } catch (final Exception e) { // 无法创建当前类型的对象,尝试创建父类型对象 final Class superclass = collectionType.getSuperclass(); @@ -1407,7 +1408,7 @@ public class CollUtil { if (bean instanceof Map) { return ((Map) bean).get(fieldName); } else { - return ReflectUtil.getFieldValue(bean, fieldName); + return FieldUtil.getFieldValue(bean, fieldName); } }, ignoreNull); } @@ -1500,7 +1501,7 @@ public class CollUtil { } // 普通Bean - final Object value = ReflectUtil.getFieldValue(t, fieldName); + final Object value = FieldUtil.getFieldValue(t, fieldName); return ObjUtil.equal(value, fieldValue); }); } @@ -2648,7 +2649,7 @@ public class CollUtil { // 非Bean放在同一子分组中 return 0; } - final Object value = ReflectUtil.getFieldValue(t, fieldName); + final Object value = FieldUtil.getFieldValue(t, fieldName); final int hash = fieldNameList.indexOf(value); if (hash < 0) { fieldNameList.add(value); diff --git a/hutool-core/src/main/java/cn/hutool/core/collection/iter/IterUtil.java b/hutool-core/src/main/java/cn/hutool/core/collection/iter/IterUtil.java index 2264783c1..233f1766f 100644 --- a/hutool-core/src/main/java/cn/hutool/core/collection/iter/IterUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/collection/iter/IterUtil.java @@ -5,14 +5,14 @@ import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.func.Editor; import cn.hutool.core.lang.func.Filter; -import cn.hutool.core.lang.func.Matcher; import cn.hutool.core.lang.func.Func1; +import cn.hutool.core.lang.func.Matcher; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.reflect.FieldUtil; import cn.hutool.core.reflect.MethodUtil; import cn.hutool.core.text.StrJoiner; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.reflect.ReflectUtil; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -179,7 +179,7 @@ public class IterUtil { */ @SuppressWarnings("unchecked") public static Map fieldValueMap(final Iterator iter, final String fieldName) { - return toMap(iter, new HashMap<>(), (value) -> (K) ReflectUtil.getFieldValue(value, fieldName)); + return toMap(iter, new HashMap<>(), (value) -> (K) FieldUtil.getFieldValue(value, fieldName)); } /** @@ -196,8 +196,8 @@ public class IterUtil { @SuppressWarnings("unchecked") public static Map fieldValueAsMap(final Iterator iter, final String fieldNameForKey, final String fieldNameForValue) { return toMap(iter, new HashMap<>(), - (value) -> (K) ReflectUtil.getFieldValue(value, fieldNameForKey), - (value) -> (V) ReflectUtil.getFieldValue(value, fieldNameForValue) + (value) -> (K) FieldUtil.getFieldValue(value, fieldNameForKey), + (value) -> (V) FieldUtil.getFieldValue(value, fieldNameForValue) ); } @@ -229,7 +229,7 @@ public class IterUtil { V value; while (iter.hasNext()) { value = iter.next(); - result.add(ReflectUtil.getFieldValue(value, fieldName)); + result.add(FieldUtil.getFieldValue(value, fieldName)); } } return result; diff --git a/hutool-core/src/main/java/cn/hutool/core/comparator/FieldComparator.java b/hutool-core/src/main/java/cn/hutool/core/comparator/FieldComparator.java index 01342a86b..0074fb6a7 100644 --- a/hutool-core/src/main/java/cn/hutool/core/comparator/FieldComparator.java +++ b/hutool-core/src/main/java/cn/hutool/core/comparator/FieldComparator.java @@ -1,7 +1,7 @@ package cn.hutool.core.comparator; import cn.hutool.core.lang.Assert; -import cn.hutool.core.reflect.ReflectUtil; +import cn.hutool.core.reflect.FieldUtil; import cn.hutool.core.text.StrUtil; import java.lang.reflect.Field; @@ -43,7 +43,7 @@ public class FieldComparator extends FuncComparator { */ public FieldComparator(final boolean nullGreater, final Field field) { super(nullGreater, (bean) -> - (Comparable) ReflectUtil.getFieldValue(bean, + (Comparable) FieldUtil.getFieldValue(bean, Assert.notNull(field, "Field must be not null!"))); } @@ -55,7 +55,7 @@ public class FieldComparator extends FuncComparator { * @return 非null字段 */ private static Field getNonNullField(final Class beanClass, final String fieldName) { - final Field field = ReflectUtil.getField(beanClass, fieldName); + final Field field = FieldUtil.getField(beanClass, fieldName); if (field == null) { throw new IllegalArgumentException(StrUtil.format("Field [{}] not found in Class [{}]", fieldName, beanClass.getName())); } diff --git a/hutool-core/src/main/java/cn/hutool/core/comparator/FieldsComparator.java b/hutool-core/src/main/java/cn/hutool/core/comparator/FieldsComparator.java index 5b986d3d5..9a285b0db 100644 --- a/hutool-core/src/main/java/cn/hutool/core/comparator/FieldsComparator.java +++ b/hutool-core/src/main/java/cn/hutool/core/comparator/FieldsComparator.java @@ -1,7 +1,7 @@ package cn.hutool.core.comparator; import cn.hutool.core.lang.Assert; -import cn.hutool.core.reflect.ReflectUtil; +import cn.hutool.core.reflect.FieldUtil; import java.lang.reflect.Field; @@ -36,7 +36,7 @@ public class FieldsComparator extends NullComparator { super(nullGreater, (a, b) -> { Field field; for (final String fieldName : fieldNames) { - field = ReflectUtil.getField(beanClass, fieldName); + field = FieldUtil.getField(beanClass, fieldName); Assert.notNull(field, "Field [{}] not found in Class [{}]", fieldName, beanClass.getName()); final int compare = new FieldComparator<>(field).compare(a, b); if (0 != compare) { diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java index 497227886..d59cb62fe 100755 --- a/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/ConverterRegistry.java @@ -35,12 +35,12 @@ import cn.hutool.core.convert.impl.URLConverter; import cn.hutool.core.convert.impl.UUIDConverter; import cn.hutool.core.date.DateTime; import cn.hutool.core.lang.Opt; -import cn.hutool.core.reflect.TypeReference; import cn.hutool.core.reflect.ClassUtil; -import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.reflect.ReflectUtil; -import cn.hutool.core.util.ServiceLoaderUtil; +import cn.hutool.core.reflect.ConstructorUtil; +import cn.hutool.core.reflect.TypeReference; import cn.hutool.core.reflect.TypeUtil; +import cn.hutool.core.util.ObjUtil; +import cn.hutool.core.util.ServiceLoaderUtil; import java.io.Serializable; import java.lang.ref.SoftReference; @@ -154,7 +154,7 @@ public class ConverterRegistry implements Serializable { * @return ConverterRegistry */ public ConverterRegistry putCustom(final Type type, final Class> converterClass) { - return putCustom(type, ReflectUtil.newInstance(converterClass)); + return putCustom(type, ConstructorUtil.newInstance(converterClass)); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java b/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java index 7746c3fb5..20f52a605 100644 --- a/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java +++ b/hutool-core/src/main/java/cn/hutool/core/convert/impl/BeanConverter.java @@ -7,9 +7,9 @@ import cn.hutool.core.bean.copier.ValueProvider; import cn.hutool.core.convert.AbstractConverter; import cn.hutool.core.convert.ConvertException; import cn.hutool.core.map.MapProxy; -import cn.hutool.core.util.ObjUtil; -import cn.hutool.core.reflect.ReflectUtil; +import cn.hutool.core.reflect.ConstructorUtil; import cn.hutool.core.reflect.TypeUtil; +import cn.hutool.core.util.ObjUtil; import java.lang.reflect.Type; import java.util.Map; @@ -75,7 +75,7 @@ public class BeanConverter extends AbstractConverter { } //限定被转换对象类型 - return BeanCopier.create(value, ReflectUtil.newInstanceIfPossible(this.beanClass), this.beanType, this.copyOptions).copy(); + return BeanCopier.create(value, ConstructorUtil.newInstanceIfPossible(this.beanClass), this.beanType, this.copyOptions).copy(); } else if(value instanceof byte[]){ // 尝试反序列化 return ObjUtil.deserialize((byte[])value); diff --git a/hutool-core/src/main/java/cn/hutool/core/exceptions/ExceptionUtil.java b/hutool-core/src/main/java/cn/hutool/core/exceptions/ExceptionUtil.java index a72638323..645e0cb50 100644 --- a/hutool-core/src/main/java/cn/hutool/core/exceptions/ExceptionUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/exceptions/ExceptionUtil.java @@ -2,9 +2,9 @@ package cn.hutool.core.exceptions; import cn.hutool.core.io.FastByteArrayOutputStream; import cn.hutool.core.map.MapUtil; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.reflect.ReflectUtil; +import cn.hutool.core.reflect.ConstructorUtil; import cn.hutool.core.text.StrUtil; +import cn.hutool.core.util.ArrayUtil; import java.io.PrintStream; import java.lang.reflect.InvocationTargetException; @@ -84,7 +84,7 @@ public class ExceptionUtil { if (wrapThrowable.isInstance(throwable)) { return (T) throwable; } - return ReflectUtil.newInstance(wrapThrowable, throwable); + return ConstructorUtil.newInstance(wrapThrowable, throwable); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/Singleton.java b/hutool-core/src/main/java/cn/hutool/core/lang/Singleton.java index 1b9f4e4a3..18e457896 100755 --- a/hutool-core/src/main/java/cn/hutool/core/lang/Singleton.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/Singleton.java @@ -2,7 +2,7 @@ package cn.hutool.core.lang; import cn.hutool.core.classloader.ClassLoaderUtil; import cn.hutool.core.lang.func.Func0; -import cn.hutool.core.reflect.ReflectUtil; +import cn.hutool.core.reflect.ConstructorUtil; import cn.hutool.core.text.StrUtil; import cn.hutool.core.util.ArrayUtil; @@ -36,7 +36,7 @@ public final class Singleton { public static T get(final Class clazz, final Object... params) { Assert.notNull(clazz, "Class must be not null !"); final String key = buildKey(clazz.getName(), params); - return get(key, () -> ReflectUtil.newInstance(clazz, params)); + return get(key, () -> ConstructorUtil.newInstance(clazz, params)); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/generator/ObjectGenerator.java b/hutool-core/src/main/java/cn/hutool/core/lang/generator/ObjectGenerator.java index 66d484e2d..82d7bd466 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/generator/ObjectGenerator.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/generator/ObjectGenerator.java @@ -1,6 +1,6 @@ package cn.hutool.core.lang.generator; -import cn.hutool.core.reflect.ReflectUtil; +import cn.hutool.core.reflect.ConstructorUtil; /** * 对象生成器,通过指定对象的Class类型,调用next方法时生成新的对象。 @@ -23,6 +23,6 @@ public class ObjectGenerator implements Generator { @Override public T next() { - return ReflectUtil.newInstanceIfPossible(this.clazz); + return ConstructorUtil.newInstanceIfPossible(this.clazz); } } diff --git a/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java b/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java index 3bfe1e985..115b7b45e 100755 --- a/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/map/MapUtil.java @@ -4,10 +4,10 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.convert.Convert; import cn.hutool.core.lang.func.Editor; import cn.hutool.core.lang.func.Filter; +import cn.hutool.core.reflect.ConstructorUtil; import cn.hutool.core.reflect.TypeReference; -import cn.hutool.core.util.ArrayUtil; -import cn.hutool.core.reflect.ReflectUtil; import cn.hutool.core.text.StrUtil; +import cn.hutool.core.util.ArrayUtil; import java.util.AbstractMap; import java.util.ArrayList; @@ -244,7 +244,7 @@ public class MapUtil { if (mapType.isAssignableFrom(AbstractMap.class)) { return new HashMap<>(); } else { - return (Map) ReflectUtil.newInstance(mapType); + return (Map) ConstructorUtil.newInstance(mapType); } } @@ -630,7 +630,7 @@ public class MapUtil { return map; } - Map map2 = ReflectUtil.newInstanceIfPossible(map.getClass()); + Map map2 = ConstructorUtil.newInstanceIfPossible(map.getClass()); if (null == map2) { map2 = new HashMap<>(map.size(), 1f); } @@ -706,7 +706,7 @@ public class MapUtil { return map; } - Map map2 = ReflectUtil.newInstanceIfPossible(map.getClass()); + Map map2 = ConstructorUtil.newInstanceIfPossible(map.getClass()); if (null == map2) { map2 = new HashMap<>(map.size(), 1f); } diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/ConstructorUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/ConstructorUtil.java new file mode 100644 index 000000000..f36b8bcf5 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/ConstructorUtil.java @@ -0,0 +1,197 @@ +package cn.hutool.core.reflect; + +import cn.hutool.core.exceptions.UtilException; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.map.WeakConcurrentMap; +import cn.hutool.core.util.ArrayUtil; + +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * 反射中{@link Constructor}构造工具类,包括获取构造类和通过构造实例化对象相关工具 + * + * @author looly + */ +public class ConstructorUtil { + /** + * 构造对象缓存 + */ + private static final WeakConcurrentMap, Constructor[]> CONSTRUCTORS_CACHE = new WeakConcurrentMap<>(); + // --------------------------------------------------------------------------------------------------------- Constructor + + /** + * 查找类中的指定参数的构造方法,如果找到构造方法,会自动设置可访问为true + * + * @param 对象类型 + * @param clazz 类 + * @param parameterTypes 参数类型,只要任何一个参数是指定参数的父类或接口或相等即可,此参数可以不传 + * @return 构造方法,如果未找到返回null + */ + @SuppressWarnings("unchecked") + public static Constructor getConstructor(final Class clazz, final Class... parameterTypes) { + if (null == clazz) { + return null; + } + + final Constructor[] constructors = getConstructors(clazz); + Class[] pts; + for (final Constructor constructor : constructors) { + pts = constructor.getParameterTypes(); + if (ClassUtil.isAllAssignableFrom(pts, parameterTypes)) { + // 构造可访问 + ReflectUtil.setAccessible(constructor); + return (Constructor) constructor; + } + } + return null; + } + + /** + * 获得一个类中所有构造列表 + * + * @param 构造的对象类型 + * @param beanClass 类,非{@code null} + * @return 字段列表 + * @throws SecurityException 安全检查异常 + */ + @SuppressWarnings("unchecked") + public static Constructor[] getConstructors(final Class beanClass) throws SecurityException { + Assert.notNull(beanClass); + return (Constructor[]) CONSTRUCTORS_CACHE.computeIfAbsent(beanClass, () -> getConstructorsDirectly(beanClass)); + } + + /** + * 获得一个类中所有构造列表,直接反射获取,无缓存 + * + * @param beanClass 类 + * @return 字段列表 + * @throws SecurityException 安全检查异常 + */ + public static Constructor[] getConstructorsDirectly(final Class beanClass) throws SecurityException { + return beanClass.getDeclaredConstructors(); + } + + // --------------------------------------------------------------------------------------------------------- newInstance + + /** + * 实例化对象 + * + * @param 对象类型 + * @param clazz 类名 + * @return 对象 + * @throws UtilException 包装各类异常 + */ + @SuppressWarnings("unchecked") + public static T newInstance(final String clazz) throws UtilException { + try { + return (T) Class.forName(clazz).newInstance(); + } catch (final Exception e) { + throw new UtilException(e, "Instance class [{}] error!", clazz); + } + } + + /** + * 实例化对象 + * + * @param 对象类型 + * @param clazz 类 + * @param params 构造函数参数 + * @return 对象 + * @throws UtilException 包装各类异常 + */ + public static T newInstance(final Class clazz, final Object... params) throws UtilException { + if (ArrayUtil.isEmpty(params)) { + final Constructor constructor = getConstructor(clazz); + try { + return constructor.newInstance(); + } catch (final Exception e) { + throw new UtilException(e, "Instance class [{}] error!", clazz); + } + } + + final Class[] paramTypes = ClassUtil.getClasses(params); + final Constructor constructor = getConstructor(clazz, paramTypes); + if (null == constructor) { + throw new UtilException("No Constructor matched for parameter types: [{}]", new Object[]{paramTypes}); + } + try { + return constructor.newInstance(params); + } catch (final Exception e) { + throw new UtilException(e, "Instance class [{}] error!", clazz); + } + } + + /** + * 尝试遍历并调用此类的所有构造方法,直到构造成功并返回 + *

+ * 对于某些特殊的接口,按照其默认实现实例化,例如: + *

+	 *     Map       -》 HashMap
+	 *     Collction -》 ArrayList
+	 *     List      -》 ArrayList
+	 *     Set       -》 HashSet
+	 * 
+ * + * @param 对象类型 + * @param type 被构造的类 + * @return 构造后的对象,构造失败返回{@code null} + */ + @SuppressWarnings("unchecked") + public static T newInstanceIfPossible(Class type) { + Assert.notNull(type); + + // 原始类型 + if (type.isPrimitive()) { + return (T) ClassUtil.getPrimitiveDefaultValue(type); + } + + // 某些特殊接口的实例化按照默认实现进行 + if (type.isAssignableFrom(AbstractMap.class)) { + type = (Class) HashMap.class; + } else if (type.isAssignableFrom(List.class)) { + type = (Class) ArrayList.class; + } else if (type.isAssignableFrom(Set.class)) { + type = (Class) HashSet.class; + } + + try { + return newInstance(type); + } catch (final Exception e) { + // ignore + // 默认构造不存在的情况下查找其它构造 + } + + // 枚举 + if (type.isEnum()) { + return type.getEnumConstants()[0]; + } + + // 数组 + if (type.isArray()) { + return (T) Array.newInstance(type.getComponentType(), 0); + } + + final Constructor[] constructors = getConstructors(type); + Class[] parameterTypes; + for (final Constructor constructor : constructors) { + parameterTypes = constructor.getParameterTypes(); + if (0 == parameterTypes.length) { + continue; + } + ReflectUtil.setAccessible(constructor); + try { + return constructor.newInstance(ClassUtil.getDefaultValues(parameterTypes)); + } catch (final Exception ignore) { + // 构造出错时继续尝试下一种构造方式 + } + } + return null; + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/FieldUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/FieldUtil.java new file mode 100644 index 000000000..3229d4e53 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/FieldUtil.java @@ -0,0 +1,301 @@ +package cn.hutool.core.reflect; + +import cn.hutool.core.annotation.Alias; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.exceptions.UtilException; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.lang.func.Filter; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.map.WeakConcurrentMap; +import cn.hutool.core.text.StrUtil; +import cn.hutool.core.util.ArrayUtil; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +/** + * 反射中{@link Field}字段工具类,包括字段获取和字段赋值。 + * + * @author looly + */ +public class FieldUtil { + + /** + * 字段缓存 + */ + private static final WeakConcurrentMap, Field[]> FIELDS_CACHE = new WeakConcurrentMap<>(); + + // --------------------------------------------------------------------------------------------------------- Field + + /** + * 查找指定类中是否包含指定名称对应的字段,包括所有字段(包括非public字段),也包括父类和Object类的字段 + * + * @param beanClass 被查找字段的类,不能为null + * @param name 字段名 + * @return 是否包含字段 + * @throws SecurityException 安全异常 + * @since 4.1.21 + */ + public static boolean hasField(final Class beanClass, final String name) throws SecurityException { + return null != getField(beanClass, name); + } + + /** + * 获取字段名,如果存在{@link Alias}注解,读取注解的值作为名称 + * + * @param field 字段 + * @return 字段名 + * @since 5.1.6 + */ + public static String getFieldName(final Field field) { + if (null == field) { + return null; + } + + final Alias alias = field.getAnnotation(Alias.class); + if (null != alias) { + return alias.value(); + } + + return field.getName(); + } + + /** + * 查找指定类中的指定name的字段(包括非public字段),也包括父类和Object类的字段, 字段不存在则返回{@code null} + * + * @param beanClass 被查找字段的类,不能为null + * @param name 字段名 + * @return 字段 + * @throws SecurityException 安全异常 + */ + public static Field getField(final Class beanClass, final String name) throws SecurityException { + final Field[] fields = getFields(beanClass); + return ArrayUtil.firstMatch((field) -> name.equals(getFieldName(field)), fields); + } + + /** + * 获取本类定义的指定名称的字段,包括私有字段,但是不包括父类字段 + * + * @param beanClass Bean的Class + * @param name 字段名称 + * @return 字段对象,如果未找到返回{@code null} + */ + public static Field getDeClearField(final Class beanClass, final String name) { + try { + return beanClass.getDeclaredField(name); + } catch (NoSuchFieldException e) { + return null; + } + } + + /** + * 获取指定类中字段名和字段对应的有序Map,包括其父类中的字段
+ * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 + * + * @param beanClass 类 + * @return 字段名和字段对应的Map,有序 + * @since 5.0.7 + */ + public static Map getFieldMap(final Class beanClass) { + final Field[] fields = getFields(beanClass); + final HashMap map = MapUtil.newHashMap(fields.length, true); + for (final Field field : fields) { + map.put(field.getName(), field); + } + return map; + } + + /** + * 获得一个类中所有字段列表,包括其父类中的字段
+ * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 + * + * @param beanClass 类 + * @return 字段列表 + * @throws SecurityException 安全检查异常 + */ + public static Field[] getFields(final Class beanClass) throws SecurityException { + Assert.notNull(beanClass); + return FIELDS_CACHE.computeIfAbsent(beanClass, () -> getFieldsDirectly(beanClass, true)); + } + + + /** + * 获得一个类中所有满足条件的字段列表,包括其父类中的字段
+ * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 + * + * @param beanClass 类 + * @param fieldFilter field过滤器,过滤掉不需要的field + * @return 字段列表 + * @throws SecurityException 安全检查异常 + * @since 5.7.14 + */ + public static Field[] getFields(final Class beanClass, final Filter fieldFilter) throws SecurityException { + return ArrayUtil.filter(getFields(beanClass), fieldFilter); + } + + /** + * 获得一个类中所有字段列表,直接反射获取,无缓存
+ * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 + * + * @param beanClass 类 + * @param withSuperClassFields 是否包括父类的字段列表 + * @return 字段列表 + * @throws SecurityException 安全检查异常 + */ + public static Field[] getFieldsDirectly(final Class beanClass, final boolean withSuperClassFields) throws SecurityException { + Assert.notNull(beanClass); + + Field[] allFields = null; + Class searchType = beanClass; + Field[] declaredFields; + while (searchType != null) { + declaredFields = searchType.getDeclaredFields(); + if (null == allFields) { + allFields = declaredFields; + } else { + allFields = ArrayUtil.append(allFields, declaredFields); + } + searchType = withSuperClassFields ? searchType.getSuperclass() : null; + } + + return allFields; + } + + /** + * 获取字段值 + * + * @param obj 对象,如果static字段,此处为类 + * @param fieldName 字段名 + * @return 字段值 + * @throws UtilException 包装IllegalAccessException异常 + */ + public static Object getFieldValue(final Object obj, final String fieldName) throws UtilException { + if (null == obj || StrUtil.isBlank(fieldName)) { + return null; + } + return getFieldValue(obj, getField(obj instanceof Class ? (Class) obj : obj.getClass(), fieldName)); + } + + /** + * 获取静态字段值 + * + * @param field 字段 + * @return 字段值 + * @throws UtilException 包装IllegalAccessException异常 + * @since 5.1.0 + */ + public static Object getStaticFieldValue(final Field field) throws UtilException { + return getFieldValue(null, field); + } + + /** + * 获取字段值 + * + * @param obj 对象,static字段则此字段为null + * @param field 字段 + * @return 字段值 + * @throws UtilException 包装IllegalAccessException异常 + */ + public static Object getFieldValue(Object obj, final Field field) throws UtilException { + if (null == field) { + return null; + } + if (obj instanceof Class) { + // 静态字段获取时对象为null + obj = null; + } + + ReflectUtil.setAccessible(field); + final Object result; + try { + result = field.get(obj); + } catch (final IllegalAccessException e) { + throw new UtilException(e, "IllegalAccess for {}.{}", field.getDeclaringClass(), field.getName()); + } + return result; + } + + /** + * 获取所有字段的值 + * + * @param obj bean对象,如果是static字段,此处为类class + * @return 字段值数组 + * @since 4.1.17 + */ + public static Object[] getFieldsValue(final Object obj) { + if (null != obj) { + final Field[] fields = getFields(obj instanceof Class ? (Class) obj : obj.getClass()); + if (null != fields) { + final Object[] values = new Object[fields.length]; + for (int i = 0; i < fields.length; i++) { + values[i] = getFieldValue(obj, fields[i]); + } + return values; + } + } + return null; + } + + /** + * 设置字段值 + * + * @param obj 对象,static字段则此处传Class + * @param fieldName 字段名 + * @param value 值,值类型必须与字段类型匹配,不会自动转换对象类型 + * @throws UtilException 包装IllegalAccessException异常 + */ + public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws UtilException { + Assert.notNull(obj); + Assert.notBlank(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); + } + + /** + * 设置字段值 + * + * @param obj 对象,如果是static字段,此参数为null + * @param field 字段 + * @param value 值,值类型必须与字段类型匹配,不会自动转换对象类型 + * @throws UtilException UtilException 包装IllegalAccessException异常 + */ + public static void setFieldValue(final Object obj, final Field field, Object value) throws UtilException { + Assert.notNull(field, "Field in [{}] not exist !", obj); + + final Class fieldType = field.getType(); + if (null != value) { + if (false == fieldType.isAssignableFrom(value.getClass())) { + //对于类型不同的字段,尝试转换,转换失败则使用原对象类型 + final Object targetValue = Convert.convert(fieldType, value); + if (null != targetValue) { + value = targetValue; + } + } + } else { + // 获取null对应默认值,防止原始类型造成空指针问题 + value = ClassUtil.getDefaultValue(fieldType); + } + + ReflectUtil.setAccessible(field); + try { + field.set(obj instanceof Class ? null : obj, value); + } catch (final IllegalAccessException e) { + throw new UtilException(e, "IllegalAccess for {}.{}", obj, field.getName()); + } + } + + /** + * 是否为父类引用字段
+ * 当字段所在类是对象子类时(对象中定义的非static的class),会自动生成一个以"this$0"为名称的字段,指向父类对象 + * + * @param field 字段 + * @return 是否为父类引用字段 + * @since 5.7.20 + */ + public static boolean isOuterClassField(final Field field) { + return "this$0".equals(field.getName()); + } +} diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/MethodUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/MethodUtil.java index bbcbd5312..3e813f787 100644 --- a/hutool-core/src/main/java/cn/hutool/core/reflect/MethodUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/MethodUtil.java @@ -20,6 +20,11 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +/** + * 反射中{@link Method}相关工具类,包括方法获取和方法执行 + * + * @author looly + */ public class MethodUtil { /** * 方法缓存 @@ -69,7 +74,7 @@ public class MethodUtil { } final Method[] methods = getPublicMethods(clazz); - if(null == filter){ + if (null == filter) { return methods; } diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/ModifierUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/ModifierUtil.java index f7effc1ba..ad791920f 100644 --- a/hutool-core/src/main/java/cn/hutool/core/reflect/ModifierUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/ModifierUtil.java @@ -2,9 +2,7 @@ package cn.hutool.core.reflect; import cn.hutool.core.util.ArrayUtil; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.Method; +import java.lang.reflect.Member; import java.lang.reflect.Modifier; /** @@ -109,63 +107,25 @@ public class ModifierUtil { /** * 是否同时存在一个或多个修饰符(可能有多个修饰符,如果有指定的修饰符则返回true) * - * @param constructor 构造方法 + * @param member 构造、字段或方法 * @param modifierTypes 修饰符枚举 * @return 是否有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false */ - public static boolean hasModifier(final Constructor constructor, final ModifierType... modifierTypes) { - if (null == constructor || ArrayUtil.isEmpty(modifierTypes)) { + public static boolean hasModifier(final Member member, final ModifierType... modifierTypes) { + if (null == member || ArrayUtil.isEmpty(modifierTypes)) { return false; } - return 0 != (constructor.getModifiers() & modifiersToInt(modifierTypes)); + return 0 != (member.getModifiers() & modifiersToInt(modifierTypes)); } /** - * 是否同时存在一个或多个修饰符(可能有多个修饰符,如果有指定的修饰符则返回true) + * 是否是Public成员,可检测包括构造、字段和方法 * - * @param method 方法 - * @param modifierTypes 修饰符枚举 - * @return 是否有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false - */ - public static boolean hasModifier(final Method method, final ModifierType... modifierTypes) { - if (null == method || ArrayUtil.isEmpty(modifierTypes)) { - return false; - } - return 0 != (method.getModifiers() & modifiersToInt(modifierTypes)); - } - - /** - * 是否同时存在一个或多个修饰符(可能有多个修饰符,如果有指定的修饰符则返回true) - * - * @param field 字段 - * @param modifierTypes 修饰符枚举 - * @return 是否有指定修饰符,如果有返回true,否则false,如果提供参数为null返回false - */ - public static boolean hasModifier(final Field field, final ModifierType... modifierTypes) { - if (null == field || ArrayUtil.isEmpty(modifierTypes)) { - return false; - } - return 0 != (field.getModifiers() & modifiersToInt(modifierTypes)); - } - - /** - * 是否是Public字段 - * - * @param field 字段 + * @param member 构造、字段或方法 * @return 是否是Public */ - public static boolean isPublic(final Field field) { - return hasModifier(field, ModifierType.PUBLIC); - } - - /** - * 是否是Public方法 - * - * @param method 方法 - * @return 是否是Public - */ - public static boolean isPublic(final Method method) { - return hasModifier(method, ModifierType.PUBLIC); + public static boolean isPublic(final Member member) { + return hasModifier(member, ModifierType.PUBLIC); } /** @@ -179,35 +139,14 @@ public class ModifierUtil { } /** - * 是否是Public构造 + * 是否是static成员,包括构造、字段或方法 * - * @param constructor 构造 - * @return 是否是Public - */ - public static boolean isPublic(final Constructor constructor) { - return hasModifier(constructor, ModifierType.PUBLIC); - } - - /** - * 是否是static字段 - * - * @param field 字段 + * @param member 构造、字段或方法 * @return 是否是static * @since 4.0.8 */ - public static boolean isStatic(final Field field) { - return hasModifier(field, ModifierType.STATIC); - } - - /** - * 是否是static方法 - * - * @param method 方法 - * @return 是否是static - * @since 4.0.8 - */ - public static boolean isStatic(final Method method) { - return hasModifier(method, ModifierType.STATIC); + public static boolean isStatic(final Member member) { + return hasModifier(member, ModifierType.STATIC); } /** @@ -222,25 +161,14 @@ public class ModifierUtil { } /** - * 是否是合成字段(由java编译器生成的) + * 是否是合成成员(由java编译器生成的) * - * @param field 字段 + * @param member 构造、字段或方法 * @return 是否是合成字段 * @since 5.6.3 */ - public static boolean isSynthetic(final Field field) { - return field.isSynthetic(); - } - - /** - * 是否是合成方法(由java编译器生成的) - * - * @param method 方法 - * @return 是否是合成方法 - * @since 5.6.3 - */ - public static boolean isSynthetic(final Method method) { - return method.isSynthetic(); + public static boolean isSynthetic(final Member member) { + return member.isSynthetic(); } /** @@ -255,14 +183,14 @@ public class ModifierUtil { } /** - * 是否抽象方法 + * 是否抽象成员 * - * @param method 方法 + * @param member 构造、字段或方法 * @return 是否抽象方法 * @since 5.7.23 */ - public static boolean isAbstract(final Method method) { - return hasModifier(method, ModifierType.ABSTRACT); + public static boolean isAbstract(final Member member) { + return hasModifier(member, ModifierType.ABSTRACT); } //-------------------------------------------------------------------------------------------------------- Private method start diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/ReflectUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/ReflectUtil.java index afeddae2a..238730465 100644 --- a/hutool-core/src/main/java/cn/hutool/core/reflect/ReflectUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/ReflectUtil.java @@ -1,26 +1,6 @@ package cn.hutool.core.reflect; -import cn.hutool.core.annotation.Alias; -import cn.hutool.core.convert.Convert; -import cn.hutool.core.exceptions.UtilException; -import cn.hutool.core.lang.Assert; -import cn.hutool.core.lang.func.Filter; -import cn.hutool.core.map.MapUtil; -import cn.hutool.core.map.WeakConcurrentMap; -import cn.hutool.core.text.StrUtil; -import cn.hutool.core.util.ArrayUtil; - import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; /** * 反射工具类 @@ -30,457 +10,6 @@ import java.util.Set; */ public class ReflectUtil { - /** - * 构造对象缓存 - */ - private static final WeakConcurrentMap, Constructor[]> CONSTRUCTORS_CACHE = new WeakConcurrentMap<>(); - /** - * 字段缓存 - */ - private static final WeakConcurrentMap, Field[]> FIELDS_CACHE = new WeakConcurrentMap<>(); - // --------------------------------------------------------------------------------------------------------- Constructor - - /** - * 查找类中的指定参数的构造方法,如果找到构造方法,会自动设置可访问为true - * - * @param 对象类型 - * @param clazz 类 - * @param parameterTypes 参数类型,只要任何一个参数是指定参数的父类或接口或相等即可,此参数可以不传 - * @return 构造方法,如果未找到返回null - */ - @SuppressWarnings("unchecked") - public static Constructor getConstructor(final Class clazz, final Class... parameterTypes) { - if (null == clazz) { - return null; - } - - final Constructor[] constructors = getConstructors(clazz); - Class[] pts; - for (final Constructor constructor : constructors) { - pts = constructor.getParameterTypes(); - if (ClassUtil.isAllAssignableFrom(pts, parameterTypes)) { - // 构造可访问 - setAccessible(constructor); - return (Constructor) constructor; - } - } - return null; - } - - /** - * 获得一个类中所有构造列表 - * - * @param 构造的对象类型 - * @param beanClass 类,非{@code null} - * @return 字段列表 - * @throws SecurityException 安全检查异常 - */ - @SuppressWarnings("unchecked") - public static Constructor[] getConstructors(final Class beanClass) throws SecurityException { - Assert.notNull(beanClass); - return (Constructor[]) CONSTRUCTORS_CACHE.computeIfAbsent(beanClass, () -> getConstructorsDirectly(beanClass)); - } - - /** - * 获得一个类中所有构造列表,直接反射获取,无缓存 - * - * @param beanClass 类 - * @return 字段列表 - * @throws SecurityException 安全检查异常 - */ - public static Constructor[] getConstructorsDirectly(final Class beanClass) throws SecurityException { - return beanClass.getDeclaredConstructors(); - } - - // --------------------------------------------------------------------------------------------------------- Field - - /** - * 查找指定类中是否包含指定名称对应的字段,包括所有字段(包括非public字段),也包括父类和Object类的字段 - * - * @param beanClass 被查找字段的类,不能为null - * @param name 字段名 - * @return 是否包含字段 - * @throws SecurityException 安全异常 - * @since 4.1.21 - */ - public static boolean hasField(final Class beanClass, final String name) throws SecurityException { - return null != getField(beanClass, name); - } - - /** - * 获取字段名,如果存在{@link Alias}注解,读取注解的值作为名称 - * - * @param field 字段 - * @return 字段名 - * @since 5.1.6 - */ - public static String getFieldName(final Field field) { - if (null == field) { - return null; - } - - final Alias alias = field.getAnnotation(Alias.class); - if (null != alias) { - return alias.value(); - } - - return field.getName(); - } - - /** - * 查找指定类中的指定name的字段(包括非public字段),也包括父类和Object类的字段, 字段不存在则返回{@code null} - * - * @param beanClass 被查找字段的类,不能为null - * @param name 字段名 - * @return 字段 - * @throws SecurityException 安全异常 - */ - public static Field getField(final Class beanClass, final String name) throws SecurityException { - final Field[] fields = getFields(beanClass); - return ArrayUtil.firstMatch((field) -> name.equals(getFieldName(field)), fields); - } - - /** - * 获取本类定义的指定名称的字段,包括私有字段,但是不包括父类字段 - * @param beanClass Bean的Class - * @param name 字段名称 - * @return 字段对象,如果未找到返回{@code null} - */ - public static Field getDeClearField(final Class beanClass, final String name){ - try { - return beanClass.getDeclaredField(name); - } catch (NoSuchFieldException e) { - return null; - } - } - - /** - * 获取指定类中字段名和字段对应的有序Map,包括其父类中的字段
- * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 - * - * @param beanClass 类 - * @return 字段名和字段对应的Map,有序 - * @since 5.0.7 - */ - public static Map getFieldMap(final Class beanClass) { - final Field[] fields = getFields(beanClass); - final HashMap map = MapUtil.newHashMap(fields.length, true); - for (final Field field : fields) { - map.put(field.getName(), field); - } - return map; - } - - /** - * 获得一个类中所有字段列表,包括其父类中的字段
- * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 - * - * @param beanClass 类 - * @return 字段列表 - * @throws SecurityException 安全检查异常 - */ - public static Field[] getFields(final Class beanClass) throws SecurityException { - Assert.notNull(beanClass); - return FIELDS_CACHE.computeIfAbsent(beanClass, () -> getFieldsDirectly(beanClass, true)); - } - - - /** - * 获得一个类中所有满足条件的字段列表,包括其父类中的字段
- * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 - * - * @param beanClass 类 - * @param fieldFilter field过滤器,过滤掉不需要的field - * @return 字段列表 - * @throws SecurityException 安全检查异常 - * @since 5.7.14 - */ - public static Field[] getFields(final Class beanClass, final Filter fieldFilter) throws SecurityException { - return ArrayUtil.filter(getFields(beanClass), fieldFilter); - } - - /** - * 获得一个类中所有字段列表,直接反射获取,无缓存
- * 如果子类与父类中存在同名字段,则这两个字段同时存在,子类字段在前,父类字段在后。 - * - * @param beanClass 类 - * @param withSuperClassFields 是否包括父类的字段列表 - * @return 字段列表 - * @throws SecurityException 安全检查异常 - */ - public static Field[] getFieldsDirectly(final Class beanClass, final boolean withSuperClassFields) throws SecurityException { - Assert.notNull(beanClass); - - Field[] allFields = null; - Class searchType = beanClass; - Field[] declaredFields; - while (searchType != null) { - declaredFields = searchType.getDeclaredFields(); - if (null == allFields) { - allFields = declaredFields; - } else { - allFields = ArrayUtil.append(allFields, declaredFields); - } - searchType = withSuperClassFields ? searchType.getSuperclass() : null; - } - - return allFields; - } - - /** - * 获取字段值 - * - * @param obj 对象,如果static字段,此处为类 - * @param fieldName 字段名 - * @return 字段值 - * @throws UtilException 包装IllegalAccessException异常 - */ - public static Object getFieldValue(final Object obj, final String fieldName) throws UtilException { - if (null == obj || StrUtil.isBlank(fieldName)) { - return null; - } - return getFieldValue(obj, getField(obj instanceof Class ? (Class) obj : obj.getClass(), fieldName)); - } - - /** - * 获取静态字段值 - * - * @param field 字段 - * @return 字段值 - * @throws UtilException 包装IllegalAccessException异常 - * @since 5.1.0 - */ - public static Object getStaticFieldValue(final Field field) throws UtilException { - return getFieldValue(null, field); - } - - /** - * 获取字段值 - * - * @param obj 对象,static字段则此字段为null - * @param field 字段 - * @return 字段值 - * @throws UtilException 包装IllegalAccessException异常 - */ - public static Object getFieldValue(Object obj, final Field field) throws UtilException { - if (null == field) { - return null; - } - if (obj instanceof Class) { - // 静态字段获取时对象为null - obj = null; - } - - setAccessible(field); - final Object result; - try { - result = field.get(obj); - } catch (final IllegalAccessException e) { - throw new UtilException(e, "IllegalAccess for {}.{}", field.getDeclaringClass(), field.getName()); - } - return result; - } - - /** - * 获取所有字段的值 - * - * @param obj bean对象,如果是static字段,此处为类class - * @return 字段值数组 - * @since 4.1.17 - */ - public static Object[] getFieldsValue(final Object obj) { - if (null != obj) { - final Field[] fields = getFields(obj instanceof Class ? (Class) obj : obj.getClass()); - if (null != fields) { - final Object[] values = new Object[fields.length]; - for (int i = 0; i < fields.length; i++) { - values[i] = getFieldValue(obj, fields[i]); - } - return values; - } - } - return null; - } - - /** - * 设置字段值 - * - * @param obj 对象,static字段则此处传Class - * @param fieldName 字段名 - * @param value 值,值类型必须与字段类型匹配,不会自动转换对象类型 - * @throws UtilException 包装IllegalAccessException异常 - */ - public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws UtilException { - Assert.notNull(obj); - Assert.notBlank(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); - } - - /** - * 设置字段值 - * - * @param obj 对象,如果是static字段,此参数为null - * @param field 字段 - * @param value 值,值类型必须与字段类型匹配,不会自动转换对象类型 - * @throws UtilException UtilException 包装IllegalAccessException异常 - */ - public static void setFieldValue(final Object obj, final Field field, Object value) throws UtilException { - Assert.notNull(field, "Field in [{}] not exist !", obj); - - final Class fieldType = field.getType(); - if (null != value) { - if (false == fieldType.isAssignableFrom(value.getClass())) { - //对于类型不同的字段,尝试转换,转换失败则使用原对象类型 - final Object targetValue = Convert.convert(fieldType, value); - if (null != targetValue) { - value = targetValue; - } - } - } else { - // 获取null对应默认值,防止原始类型造成空指针问题 - value = ClassUtil.getDefaultValue(fieldType); - } - - setAccessible(field); - try { - field.set(obj instanceof Class ? null : obj, value); - } catch (final IllegalAccessException e) { - throw new UtilException(e, "IllegalAccess for {}.{}", obj, field.getName()); - } - } - - /** - * 是否为父类引用字段
- * 当字段所在类是对象子类时(对象中定义的非static的class),会自动生成一个以"this$0"为名称的字段,指向父类对象 - * - * @param field 字段 - * @return 是否为父类引用字段 - * @since 5.7.20 - */ - public static boolean isOuterClassField(final Field field) { - return "this$0".equals(field.getName()); - } - - // --------------------------------------------------------------------------------------------------------- newInstance - - /** - * 实例化对象 - * - * @param 对象类型 - * @param clazz 类名 - * @return 对象 - * @throws UtilException 包装各类异常 - */ - @SuppressWarnings("unchecked") - public static T newInstance(final String clazz) throws UtilException { - try { - return (T) Class.forName(clazz).newInstance(); - } catch (final Exception e) { - throw new UtilException(e, "Instance class [{}] error!", clazz); - } - } - - /** - * 实例化对象 - * - * @param 对象类型 - * @param clazz 类 - * @param params 构造函数参数 - * @return 对象 - * @throws UtilException 包装各类异常 - */ - public static T newInstance(final Class clazz, final Object... params) throws UtilException { - if (ArrayUtil.isEmpty(params)) { - final Constructor constructor = getConstructor(clazz); - try { - return constructor.newInstance(); - } catch (final Exception e) { - throw new UtilException(e, "Instance class [{}] error!", clazz); - } - } - - final Class[] paramTypes = ClassUtil.getClasses(params); - final Constructor constructor = getConstructor(clazz, paramTypes); - if (null == constructor) { - throw new UtilException("No Constructor matched for parameter types: [{}]", new Object[]{paramTypes}); - } - try { - return constructor.newInstance(params); - } catch (final Exception e) { - throw new UtilException(e, "Instance class [{}] error!", clazz); - } - } - - /** - * 尝试遍历并调用此类的所有构造方法,直到构造成功并返回 - *

- * 对于某些特殊的接口,按照其默认实现实例化,例如: - *

-	 *     Map       -》 HashMap
-	 *     Collction -》 ArrayList
-	 *     List      -》 ArrayList
-	 *     Set       -》 HashSet
-	 * 
- * - * @param 对象类型 - * @param type 被构造的类 - * @return 构造后的对象,构造失败返回{@code null} - */ - @SuppressWarnings("unchecked") - public static T newInstanceIfPossible(Class type) { - Assert.notNull(type); - - // 原始类型 - if(type.isPrimitive()){ - return (T) ClassUtil.getPrimitiveDefaultValue(type); - } - - // 某些特殊接口的实例化按照默认实现进行 - if (type.isAssignableFrom(AbstractMap.class)) { - type = (Class) HashMap.class; - } else if (type.isAssignableFrom(List.class)) { - type = (Class) ArrayList.class; - } else if (type.isAssignableFrom(Set.class)) { - type = (Class) HashSet.class; - } - - try { - return newInstance(type); - } catch (final Exception e) { - // ignore - // 默认构造不存在的情况下查找其它构造 - } - - // 枚举 - if (type.isEnum()) { - return type.getEnumConstants()[0]; - } - - // 数组 - if (type.isArray()) { - return (T) Array.newInstance(type.getComponentType(), 0); - } - - final Constructor[] constructors = getConstructors(type); - Class[] parameterTypes; - for (final Constructor constructor : constructors) { - parameterTypes = constructor.getParameterTypes(); - if (0 == parameterTypes.length) { - continue; - } - setAccessible(constructor); - try { - return constructor.newInstance(ClassUtil.getDefaultValues(parameterTypes)); - } catch (final Exception ignore) { - // 构造出错时继续尝试下一种构造方式 - } - } - return null; - } - /** * 设置方法为可访问(私有方法可以被外部调用) * diff --git a/hutool-core/src/main/java/cn/hutool/core/reflect/TypeUtil.java b/hutool-core/src/main/java/cn/hutool/core/reflect/TypeUtil.java index 5504fa40c..7ebb56b63 100644 --- a/hutool-core/src/main/java/cn/hutool/core/reflect/TypeUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/reflect/TypeUtil.java @@ -72,7 +72,7 @@ public class TypeUtil { * @since 5.4.2 */ public static Type getFieldType(final Class clazz, final String fieldName) { - return getType(ReflectUtil.getField(clazz, fieldName)); + return getType(FieldUtil.getField(clazz, fieldName)); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java b/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java index 1f1662c33..05bc88702 100644 --- a/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/util/EnumUtil.java @@ -3,8 +3,8 @@ package cn.hutool.core.util; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.func.Func1; import cn.hutool.core.lang.func.LambdaUtil; -import cn.hutool.core.reflect.ReflectUtil; import cn.hutool.core.map.MapUtil; +import cn.hutool.core.reflect.FieldUtil; import cn.hutool.core.text.StrUtil; import java.lang.reflect.Field; @@ -134,7 +134,7 @@ public class EnumUtil { value = value.toString().trim(); } - final Field[] fields = ReflectUtil.getFields(enumClass); + final Field[] fields = FieldUtil.getFields(enumClass); final Enum[] enums = enumClass.getEnumConstants(); String fieldName; for (final Field field : fields) { @@ -144,7 +144,7 @@ public class EnumUtil { continue; } for (final Enum enumObj : enums) { - if (ObjUtil.equal(value, ReflectUtil.getFieldValue(enumObj, field))) { + if (ObjUtil.equal(value, FieldUtil.getFieldValue(enumObj, field))) { return (E) enumObj; } } @@ -184,7 +184,7 @@ public class EnumUtil { } final List list = new ArrayList<>(enums.length); for (final Enum e : enums) { - list.add(ReflectUtil.getFieldValue(e, fieldName)); + list.add(FieldUtil.getFieldValue(e, fieldName)); } return list; } @@ -203,7 +203,7 @@ public class EnumUtil { */ public static List getFieldNames(final Class> clazz) { final List names = new ArrayList<>(); - final Field[] fields = ReflectUtil.getFields(clazz); + final Field[] fields = FieldUtil.getFields(clazz); String name; for (final Field field : fields) { name = field.getName(); @@ -305,7 +305,7 @@ public class EnumUtil { } final Map map = MapUtil.newHashMap(enums.length, true); for (final Enum e : enums) { - map.put(e.name(), ReflectUtil.getFieldValue(e, fieldName)); + map.put(e.name(), FieldUtil.getFieldValue(e, fieldName)); } return map; }