mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
!765 简化LambdaInfo初始化方法,调整实例化方法参数类型名称
Merge pull request !765 from Createsequence/v6-lambda
This commit is contained in:
commit
bb19e7d263
@ -1,6 +1,7 @@
|
|||||||
package cn.hutool.core.lang.func;
|
package cn.hutool.core.lang.func;
|
||||||
|
|
||||||
import cn.hutool.core.classloader.ClassLoaderUtil;
|
import cn.hutool.core.classloader.ClassLoaderUtil;
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.text.StrPool;
|
import cn.hutool.core.text.StrPool;
|
||||||
|
|
||||||
import java.lang.invoke.SerializedLambda;
|
import java.lang.invoke.SerializedLambda;
|
||||||
@ -16,7 +17,8 @@ import java.lang.reflect.Type;
|
|||||||
*/
|
*/
|
||||||
public class LambdaInfo {
|
public class LambdaInfo {
|
||||||
|
|
||||||
private final Type[] instantiatedTypes;
|
private static final Type[] EMPTY_TYPE = new Type[0];
|
||||||
|
private final Type[] instantiatedMethodParameterTypes;
|
||||||
private final Type[] parameterTypes;
|
private final Type[] parameterTypes;
|
||||||
private final Type returnType;
|
private final Type returnType;
|
||||||
private final String name;
|
private final String name;
|
||||||
@ -25,53 +27,54 @@ public class LambdaInfo {
|
|||||||
private final SerializedLambda lambda;
|
private final SerializedLambda lambda;
|
||||||
|
|
||||||
public LambdaInfo(final Executable executable, final SerializedLambda lambda) {
|
public LambdaInfo(final Executable executable, final SerializedLambda lambda) {
|
||||||
if (executable instanceof Method) {
|
// return type
|
||||||
final Method method = (Method) executable;
|
final boolean isMethod = executable instanceof Method;
|
||||||
this.parameterTypes = method.getGenericParameterTypes();
|
final boolean isConstructor = executable instanceof Constructor;
|
||||||
this.returnType = method.getGenericReturnType();
|
Assert.isTrue(isMethod || isConstructor, "Unsupported executable type: " + executable.getClass());
|
||||||
this.name = method.getName();
|
this.returnType = isMethod ?
|
||||||
this.clazz = method.getDeclaringClass();
|
((Method)executable).getGenericReturnType() : ((Constructor<?>)executable).getDeclaringClass();
|
||||||
} else if (executable instanceof Constructor) {
|
|
||||||
final Constructor<?> constructor = (Constructor<?>) executable;
|
// lambda info
|
||||||
this.parameterTypes = constructor.getGenericParameterTypes();
|
this.parameterTypes = executable.getGenericParameterTypes();
|
||||||
this.returnType = constructor.getDeclaringClass();
|
this.name = executable.getName();
|
||||||
this.name = constructor.getName();
|
this.clazz = executable.getDeclaringClass();
|
||||||
this.clazz = constructor.getDeclaringClass();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Unsupported executable type: " + executable.getClass());
|
|
||||||
}
|
|
||||||
final int index = lambda.getInstantiatedMethodType().indexOf(";)");
|
|
||||||
if (index > -1) {
|
|
||||||
final String className = lambda.getInstantiatedMethodType().substring(1, index + 1);
|
|
||||||
final String[] instantiatedTypeNames = className.split(";");
|
|
||||||
final Type[] types = new Type[instantiatedTypeNames.length];
|
|
||||||
for (int i = 0; i < instantiatedTypeNames.length; i++) {
|
|
||||||
final boolean isArray = instantiatedTypeNames[i].startsWith(StrPool.BRACKET_START);
|
|
||||||
if (isArray && !instantiatedTypeNames[i].endsWith(";")) {
|
|
||||||
// 如果是数组,需要以 ";" 结尾才能加载
|
|
||||||
instantiatedTypeNames[i] += ";";
|
|
||||||
} else {
|
|
||||||
if (instantiatedTypeNames[i].startsWith("L")) {
|
|
||||||
// 如果以 "L" 开头,删除 L
|
|
||||||
instantiatedTypeNames[i] = instantiatedTypeNames[i].substring(1);
|
|
||||||
}
|
|
||||||
if (instantiatedTypeNames[i].endsWith(";")) {
|
|
||||||
// 如果以 ";" 结尾,删除 ";"
|
|
||||||
instantiatedTypeNames[i] = instantiatedTypeNames[i].substring(0, instantiatedTypeNames[i].length() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
types[i] = ClassLoaderUtil.loadClass(instantiatedTypeNames[i]);
|
|
||||||
}
|
|
||||||
this.instantiatedTypes = types;
|
|
||||||
} else {
|
|
||||||
this.instantiatedTypes = new Type[0];
|
|
||||||
}
|
|
||||||
this.executable = executable;
|
this.executable = executable;
|
||||||
this.lambda = lambda;
|
this.lambda = lambda;
|
||||||
|
|
||||||
|
// types
|
||||||
|
final int index = lambda.getInstantiatedMethodType().indexOf(";)");
|
||||||
|
this.instantiatedMethodParameterTypes = (index > -1) ? getInstantiatedMethodParamTypes(lambda, index) : EMPTY_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type[] getInstantiatedTypes() {
|
/**
|
||||||
return instantiatedTypes;
|
* 根据lambda对象的方法签名信息,解析获得实际的参数类型
|
||||||
|
*/
|
||||||
|
private Type[] getInstantiatedMethodParamTypes(SerializedLambda lambda, int index) {
|
||||||
|
final String className = lambda.getInstantiatedMethodType().substring(1, index + 1);
|
||||||
|
final String[] instantiatedTypeNames = className.split(";");
|
||||||
|
final Type[] types = new Type[instantiatedTypeNames.length];
|
||||||
|
for (int i = 0; i < instantiatedTypeNames.length; i++) {
|
||||||
|
final boolean isArray = instantiatedTypeNames[i].startsWith(StrPool.BRACKET_START);
|
||||||
|
if (isArray && !instantiatedTypeNames[i].endsWith(";")) {
|
||||||
|
// 如果是数组,需要以 ";" 结尾才能加载
|
||||||
|
instantiatedTypeNames[i] += ";";
|
||||||
|
} else {
|
||||||
|
if (instantiatedTypeNames[i].startsWith("L")) {
|
||||||
|
// 如果以 "L" 开头,删除 L
|
||||||
|
instantiatedTypeNames[i] = instantiatedTypeNames[i].substring(1);
|
||||||
|
}
|
||||||
|
if (instantiatedTypeNames[i].endsWith(";")) {
|
||||||
|
// 如果以 ";" 结尾,删除 ";"
|
||||||
|
instantiatedTypeNames[i] = instantiatedTypeNames[i].substring(0, instantiatedTypeNames[i].length() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
types[i] = ClassLoaderUtil.loadClass(instantiatedTypeNames[i]);
|
||||||
|
}
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type[] getInstantiatedMethodParameterTypes() {
|
||||||
|
return instantiatedMethodParameterTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type[] getParameterTypes() {
|
public Type[] getParameterTypes() {
|
||||||
|
@ -61,7 +61,7 @@ public class LambdaUtil {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <R, T extends Serializable> Class<R> getRealClass(final T func) {
|
public static <R, T extends Serializable> Class<R> getRealClass(final T func) {
|
||||||
final LambdaInfo lambdaInfo = resolve(func);
|
final LambdaInfo lambdaInfo = resolve(func);
|
||||||
return (Class<R>) Opt.of(lambdaInfo).map(LambdaInfo::getInstantiatedTypes).filter(types -> types.length != 0).map(types -> types[types.length - 1]).orElseGet(lambdaInfo::getClazz);
|
return (Class<R>) Opt.of(lambdaInfo).map(LambdaInfo::getInstantiatedMethodParameterTypes).filter(types -> types.length != 0).map(types -> types[types.length - 1]).orElseGet(lambdaInfo::getClazz);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user