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;
|
||||
|
||||
import cn.hutool.core.classloader.ClassLoaderUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.text.StrPool;
|
||||
|
||||
import java.lang.invoke.SerializedLambda;
|
||||
@ -16,7 +17,8 @@ import java.lang.reflect.Type;
|
||||
*/
|
||||
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 returnType;
|
||||
private final String name;
|
||||
@ -25,53 +27,54 @@ public class LambdaInfo {
|
||||
private final SerializedLambda lambda;
|
||||
|
||||
public LambdaInfo(final Executable executable, final SerializedLambda lambda) {
|
||||
if (executable instanceof Method) {
|
||||
final Method method = (Method) executable;
|
||||
this.parameterTypes = method.getGenericParameterTypes();
|
||||
this.returnType = method.getGenericReturnType();
|
||||
this.name = method.getName();
|
||||
this.clazz = method.getDeclaringClass();
|
||||
} else if (executable instanceof Constructor) {
|
||||
final Constructor<?> constructor = (Constructor<?>) executable;
|
||||
this.parameterTypes = constructor.getGenericParameterTypes();
|
||||
this.returnType = constructor.getDeclaringClass();
|
||||
this.name = constructor.getName();
|
||||
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];
|
||||
}
|
||||
// return type
|
||||
final boolean isMethod = executable instanceof Method;
|
||||
final boolean isConstructor = executable instanceof Constructor;
|
||||
Assert.isTrue(isMethod || isConstructor, "Unsupported executable type: " + executable.getClass());
|
||||
this.returnType = isMethod ?
|
||||
((Method)executable).getGenericReturnType() : ((Constructor<?>)executable).getDeclaringClass();
|
||||
|
||||
// lambda info
|
||||
this.parameterTypes = executable.getGenericParameterTypes();
|
||||
this.name = executable.getName();
|
||||
this.clazz = executable.getDeclaringClass();
|
||||
this.executable = executable;
|
||||
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() {
|
||||
|
@ -61,7 +61,7 @@ public class LambdaUtil {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <R, T extends Serializable> Class<R> getRealClass(final T 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