diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaInfo.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaInfo.java index da5fdcbad..bd62c2b22 100644 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaInfo.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaInfo.java @@ -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() { diff --git a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java index ea4d282f7..4bfa0521a 100755 --- a/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/lang/func/LambdaUtil.java @@ -61,7 +61,7 @@ public class LambdaUtil { @SuppressWarnings("unchecked") public static Class getRealClass(final T func) { final LambdaInfo lambdaInfo = resolve(func); - return (Class) Opt.of(lambdaInfo).map(LambdaInfo::getInstantiatedTypes).filter(types -> types.length != 0).map(types -> types[types.length - 1]).orElseGet(lambdaInfo::getClazz); + return (Class) Opt.of(lambdaInfo).map(LambdaInfo::getInstantiatedMethodParameterTypes).filter(types -> types.length != 0).map(types -> types[types.length - 1]).orElseGet(lambdaInfo::getClazz); } /**