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;
|
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.exception.HutoolException;
|
||||||
import org.dromara.hutool.core.lang.Assert;
|
import org.dromara.hutool.core.lang.Assert;
|
||||||
import org.dromara.hutool.core.map.WeakConcurrentMap;
|
import org.dromara.hutool.core.map.WeakConcurrentMap;
|
||||||
import org.dromara.hutool.core.reflect.lookup.LookupUtil;
|
import org.dromara.hutool.core.reflect.creator.DefaultObjectCreator;
|
||||||
import org.dromara.hutool.core.reflect.method.MethodHandleUtil;
|
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.lang.reflect.Constructor;
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 反射中{@link Constructor}构造工具类,包括获取构造类和通过构造实例化对象相关工具
|
* 反射中{@link Constructor}构造工具类,包括获取构造类和通过构造实例化对象相关工具
|
||||||
@ -99,8 +95,9 @@ public class ConstructorUtil {
|
|||||||
* @return 对象
|
* @return 对象
|
||||||
* @throws HutoolException 包装各类异常
|
* @throws HutoolException 包装各类异常
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public static <T> T newInstance(final String clazz) throws HutoolException {
|
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 包装各类异常
|
* @throws HutoolException 包装各类异常
|
||||||
*/
|
*/
|
||||||
public static <T> T newInstance(final Class<T> clazz, final Object... params) throws HutoolException {
|
public static <T> T newInstance(final Class<T> clazz, final Object... params) throws HutoolException {
|
||||||
final Class<?>[] paramTypes = ClassUtil.getClasses(params);
|
return DefaultObjectCreator.of(clazz, params).create();
|
||||||
final MethodHandle constructor = LookupUtil.findConstructor(clazz, paramTypes);
|
|
||||||
return MethodHandleUtil.invokeHandle(constructor, params);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,55 +128,7 @@ public class ConstructorUtil {
|
|||||||
* @param type 被构造的类
|
* @param type 被构造的类
|
||||||
* @return 构造后的对象,构造失败返回{@code null}
|
* @return 构造后的对象,构造失败返回{@code null}
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
public static <T> T newInstanceIfPossible(final Class<T> type) {
|
||||||
public static <T> T newInstanceIfPossible(Class<T> type) {
|
return PossibleObjectCreator.of(type).create();
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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