!765 简化LambdaInfo初始化方法,调整实例化方法参数类型名称

Merge pull request !765 from Createsequence/v6-lambda
This commit is contained in:
Looly 2022-08-23 07:26:19 +00:00 committed by Gitee
commit bb19e7d263
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 48 additions and 45 deletions

View File

@ -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,23 +27,29 @@ 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());
}
// 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(";)");
if (index > -1) {
this.instantiatedMethodParameterTypes = (index > -1) ? getInstantiatedMethodParamTypes(lambda, index) : EMPTY_TYPE;
}
/**
* 根据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];
@ -62,16 +70,11 @@ public class LambdaInfo {
}
types[i] = ClassLoaderUtil.loadClass(instantiatedTypeNames[i]);
}
this.instantiatedTypes = types;
} else {
this.instantiatedTypes = new Type[0];
}
this.executable = executable;
this.lambda = lambda;
return types;
}
public Type[] getInstantiatedTypes() {
return instantiatedTypes;
public Type[] getInstantiatedMethodParameterTypes() {
return instantiatedMethodParameterTypes;
}
public Type[] getParameterTypes() {

View File

@ -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);
}
/**