mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add object creator
This commit is contained in:
parent
659af4d5f2
commit
dbcf9eb3f3
@ -12,17 +12,13 @@
|
||||
|
||||
package org.dromara.hutool.core.reflect;
|
||||
|
||||
import org.dromara.hutool.core.classloader.ClassLoaderUtil;
|
||||
import org.dromara.hutool.core.exception.HutoolException;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.map.WeakConcurrentMap;
|
||||
import org.dromara.hutool.core.reflect.lookup.LookupUtil;
|
||||
import org.dromara.hutool.core.reflect.method.MethodHandleUtil;
|
||||
import org.dromara.hutool.core.reflect.creator.DefaultObjectCreator;
|
||||
import org.dromara.hutool.core.reflect.creator.PossibleObjectCreator;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 反射中{@link Constructor}构造工具类,包括获取构造类和通过构造实例化对象相关工具
|
||||
@ -99,8 +95,9 @@ public class ConstructorUtil {
|
||||
* @return 对象
|
||||
* @throws HutoolException 包装各类异常
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T newInstance(final String clazz) throws HutoolException {
|
||||
return newInstance(ClassLoaderUtil.loadClass(clazz));
|
||||
return (T) DefaultObjectCreator.of(clazz).create();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,9 +110,7 @@ public class ConstructorUtil {
|
||||
* @throws HutoolException 包装各类异常
|
||||
*/
|
||||
public static <T> T newInstance(final Class<T> clazz, final Object... params) throws HutoolException {
|
||||
final Class<?>[] paramTypes = ClassUtil.getClasses(params);
|
||||
final MethodHandle constructor = LookupUtil.findConstructor(clazz, paramTypes);
|
||||
return MethodHandleUtil.invokeHandle(constructor, params);
|
||||
return DefaultObjectCreator.of(clazz, params).create();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,55 +128,7 @@ public class ConstructorUtil {
|
||||
* @param type 被构造的类
|
||||
* @return 构造后的对象,构造失败返回{@code null}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T newInstanceIfPossible(Class<T> type) {
|
||||
Assert.notNull(type);
|
||||
|
||||
// 原始类型
|
||||
if (type.isPrimitive()) {
|
||||
return (T) ClassUtil.getPrimitiveDefaultValue(type);
|
||||
}
|
||||
|
||||
// 某些特殊接口的实例化按照默认实现进行
|
||||
if (type.isAssignableFrom(AbstractMap.class)) {
|
||||
type = (Class<T>) HashMap.class;
|
||||
} else if (type.isAssignableFrom(List.class)) {
|
||||
type = (Class<T>) ArrayList.class;
|
||||
} else if (type.isAssignableFrom(Set.class)) {
|
||||
type = (Class<T>) 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<T>[] constructors = getConstructors(type);
|
||||
Class<?>[] parameterTypes;
|
||||
for (final Constructor<T> 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;
|
||||
public static <T> T newInstanceIfPossible(final Class<T> type) {
|
||||
return PossibleObjectCreator.of(type).create();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.reflect.creator;
|
||||
|
||||
import org.dromara.hutool.core.classloader.ClassLoaderUtil;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.reflect.ClassUtil;
|
||||
import org.dromara.hutool.core.reflect.lookup.LookupUtil;
|
||||
import org.dromara.hutool.core.reflect.method.MethodHandleUtil;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
|
||||
/**
|
||||
* 默认对象实例化器<br>
|
||||
* 通过传入对象类型和构造函数的参数,调用对应的构造方法创建对象。
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
*/
|
||||
public class DefaultObjectCreator<T> implements ObjectCreator<T> {
|
||||
|
||||
/**
|
||||
* 创建默认的对象实例化器
|
||||
*
|
||||
* @param fullClassName 类名全程
|
||||
* @param <T> 对象类型
|
||||
* @return DefaultObjectCreator
|
||||
*/
|
||||
public static <T> DefaultObjectCreator<T> of(final String fullClassName) {
|
||||
return of(ClassLoaderUtil.loadClass(fullClassName));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建默认的对象实例化器
|
||||
*
|
||||
* @param clazz 实例化的类
|
||||
* @param params 构造参数,无参数空
|
||||
* @param <T> 对象类型
|
||||
* @return DefaultObjectCreator
|
||||
*/
|
||||
public static <T> DefaultObjectCreator<T> of(final Class<T> clazz, final Object... params) {
|
||||
return new DefaultObjectCreator<>(clazz, params);
|
||||
}
|
||||
|
||||
final MethodHandle constructor;
|
||||
final Object[] params;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param clazz 实例化的类
|
||||
* @param params 构造参数,无参数空
|
||||
*/
|
||||
public DefaultObjectCreator(final Class<T> clazz, final Object... params) {
|
||||
final Class<?>[] paramTypes = ClassUtil.getClasses(params);
|
||||
this.constructor = LookupUtil.findConstructor(clazz, paramTypes);
|
||||
Assert.notNull(this.constructor, "Constructor not found!");
|
||||
this.params = params;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T create() {
|
||||
return MethodHandleUtil.invokeHandle(constructor, params);
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.reflect.creator;
|
||||
|
||||
/**
|
||||
* 对象创建器,用于自定义创建指定类型、指定参数的对象<br>
|
||||
* 也叫对象初始化器。
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public interface ObjectCreator<T> {
|
||||
/**
|
||||
* 创建对象
|
||||
*
|
||||
* @return 对象
|
||||
*/
|
||||
T create();
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.reflect.creator;
|
||||
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
import org.dromara.hutool.core.reflect.ClassUtil;
|
||||
import org.dromara.hutool.core.reflect.ConstructorUtil;
|
||||
import org.dromara.hutool.core.reflect.ReflectUtil;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 尝试方式对象实例化器<br>
|
||||
* 通过判断类型或调用可能的构造,构建对象,支持:
|
||||
* <ul>
|
||||
* <li>原始类型</li>
|
||||
* <li>接口或抽象类型</li>
|
||||
* <li>枚举</li>
|
||||
* <li>数组</li>
|
||||
* <li>使用默认参数的构造方法</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* 对于接口或抽象类型,构造其默认实现:
|
||||
* <pre>
|
||||
* Map -》 HashMap
|
||||
* Collction -》 ArrayList
|
||||
* List -》 ArrayList
|
||||
* Set -》 HashSet
|
||||
* </pre>
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
*/
|
||||
public class PossibleObjectCreator<T> implements ObjectCreator<T> {
|
||||
|
||||
/**
|
||||
* 创建默认的对象实例化器
|
||||
*
|
||||
* @param clazz 实例化的类
|
||||
* @param <T> 对象类型
|
||||
* @return DefaultObjectCreator
|
||||
*/
|
||||
public static <T> PossibleObjectCreator<T> of(final Class<T> clazz) {
|
||||
return new PossibleObjectCreator<>(clazz);
|
||||
}
|
||||
|
||||
final Class<T> clazz;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param clazz 实例化的类
|
||||
*/
|
||||
public PossibleObjectCreator(final Class<T> clazz) {
|
||||
this.clazz = Assert.notNull(clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T create() {
|
||||
Class<T> type = this.clazz;
|
||||
|
||||
// 原始类型
|
||||
if (type.isPrimitive()) {
|
||||
return (T) ClassUtil.getPrimitiveDefaultValue(type);
|
||||
}
|
||||
|
||||
// 某些特殊接口的实例化按照默认实现进行
|
||||
if (type.isAssignableFrom(AbstractMap.class)) {
|
||||
type = (Class<T>) HashMap.class;
|
||||
} else if (type.isAssignableFrom(List.class)) {
|
||||
type = (Class<T>) ArrayList.class;
|
||||
} else if (type.isAssignableFrom(Set.class)) {
|
||||
type = (Class<T>) HashSet.class;
|
||||
}
|
||||
|
||||
try {
|
||||
return DefaultObjectCreator.of(type).create();
|
||||
} catch (final Exception e) {
|
||||
// ignore
|
||||
// 默认构造不存在的情况下查找其它构造
|
||||
}
|
||||
|
||||
// 枚举
|
||||
if (type.isEnum()) {
|
||||
return type.getEnumConstants()[0];
|
||||
}
|
||||
|
||||
// 数组
|
||||
if (type.isArray()) {
|
||||
return (T) Array.newInstance(type.getComponentType(), 0);
|
||||
}
|
||||
|
||||
final Constructor<T>[] constructors = ConstructorUtil.getConstructors(type);
|
||||
Class<?>[] parameterTypes;
|
||||
for (final Constructor<T> 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;
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 对象实例化器,对象创建器
|
||||
*
|
||||
* @author looly
|
||||
* @since 6.0.0
|
||||
*/
|
||||
package org.dromara.hutool.core.reflect.creator;
|
Loading…
x
Reference in New Issue
Block a user