mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
重构LambdaUtil,强化原有的SerializedLambda缓存为自定义LambdaInfo,该类额外存储了lambda反射类,且可以获取到lambda中使用的外部变量参数;额外在ReflectUtil新增了部分函数,用于获取描述符
This commit is contained in:
@@ -1,14 +1,15 @@
|
||||
package cn.hutool.core.lang.func;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.invoke.MethodHandleInfo;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public class LambdaUtilTest {
|
||||
|
||||
@Test
|
||||
@@ -25,60 +26,80 @@ public class LambdaUtilTest {
|
||||
|
||||
@Test
|
||||
public void resolveTest() {
|
||||
// 引用构造函数
|
||||
Assert.assertEquals(MethodHandleInfo.REF_newInvokeSpecial,
|
||||
LambdaUtil.resolve(MyTeacher::new).getImplMethodKind());
|
||||
// 数组构造函数引用
|
||||
Assert.assertEquals(MethodHandleInfo.REF_invokeStatic,
|
||||
LambdaUtil.resolve(MyTeacher[]::new).getImplMethodKind());
|
||||
// 引用静态方法
|
||||
Assert.assertEquals(MethodHandleInfo.REF_invokeStatic,
|
||||
LambdaUtil.resolve(MyTeacher::takeAge).getImplMethodKind());
|
||||
// 引用特定对象的实例方法
|
||||
Assert.assertEquals(MethodHandleInfo.REF_invokeVirtual,
|
||||
LambdaUtil.resolve(new MyTeacher()::getAge).getImplMethodKind());
|
||||
// 引用特定类型的任意对象的实例方法
|
||||
Assert.assertEquals(MethodHandleInfo.REF_invokeVirtual,
|
||||
LambdaUtil.resolve(MyTeacher::getAge).getImplMethodKind());
|
||||
Stream.<Runnable>of(() -> {
|
||||
// 引用构造函数
|
||||
Func0<MyTeacher> lambda = MyTeacher::new;
|
||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
||||
Assert.assertEquals(0, lambdaInfo.getParameterTypes().length);
|
||||
Assert.assertEquals(MyTeacher.class, lambdaInfo.getReturnType());
|
||||
}, () -> {
|
||||
// 数组构造函数引用(此处数组构造参数)
|
||||
Func1<Integer, MyTeacher[]> lambda = MyTeacher[]::new;
|
||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(lambda);
|
||||
Assert.assertEquals(int.class, lambdaInfo.getParameterTypes()[0]);
|
||||
Assert.assertEquals(MyTeacher.class, ((Class<Array>) lambdaInfo.getReturnType()).getComponentType());
|
||||
}, () -> {
|
||||
// 引用静态方法
|
||||
Func0<String> noArgsStaticMethod = MyTeacher::takeAge;
|
||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(noArgsStaticMethod);
|
||||
Assert.assertEquals(String.class, lambdaInfo.getReturnType());
|
||||
}, () -> {
|
||||
// 引用特定对象的实例方法
|
||||
Func0<String> instantiated = new MyTeacher()::getAge;
|
||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(instantiated);
|
||||
Assert.assertEquals(String.class, lambdaInfo.getReturnType());
|
||||
}, () -> {
|
||||
// 引用特定类型的任意对象的实例方法
|
||||
Func1<MyTeacher, String> annoInstantiated = MyTeacher::getAge;
|
||||
LambdaInfo lambdaInfo = LambdaUtil.resolve(annoInstantiated);
|
||||
Assert.assertEquals(String.class, lambdaInfo.getReturnType());
|
||||
}).forEach(Runnable::run);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getRealClassTest() {
|
||||
// 引用特定类型的任意对象的实例方法
|
||||
final Class<MyTeacher> functionClass = LambdaUtil.getRealClass(MyTeacher::getAge);
|
||||
Assert.assertEquals(MyTeacher.class, functionClass);
|
||||
// 枚举测试,不会导致类型擦除
|
||||
final Class<LambdaKindEnum> enumFunctionClass = LambdaUtil.getRealClass(LambdaKindEnum::ordinal);
|
||||
Assert.assertEquals(LambdaKindEnum.class, enumFunctionClass);
|
||||
// 调用父类方法,能获取到正确的子类类型
|
||||
final Class<MyTeacher> superFunctionClass = LambdaUtil.getRealClass(MyTeacher::getId);
|
||||
Assert.assertEquals(MyTeacher.class, superFunctionClass);
|
||||
|
||||
final MyTeacher myTeacher = new MyTeacher();
|
||||
// 引用特定对象的实例方法
|
||||
final Class<MyTeacher> supplierClass = LambdaUtil.getRealClass(myTeacher::getAge);
|
||||
Assert.assertEquals(MyTeacher.class, supplierClass);
|
||||
// 枚举测试,只能获取到枚举类型
|
||||
final Class<Enum<?>> enumSupplierClass = LambdaUtil.getRealClass(LambdaKindEnum.REF_NONE::ordinal);
|
||||
Assert.assertEquals(Enum.class, enumSupplierClass);
|
||||
// 调用父类方法,只能获取到父类类型
|
||||
final Class<Entity<?>> superSupplierClass = LambdaUtil.getRealClass(myTeacher::getId);
|
||||
Assert.assertEquals(Entity.class, superSupplierClass);
|
||||
|
||||
// 引用静态带参方法,能够获取到正确的参数类型
|
||||
final Class<MyTeacher> staticFunctionClass = LambdaUtil.getRealClass(MyTeacher::takeAgeBy);
|
||||
Assert.assertEquals(MyTeacher.class, staticFunctionClass);
|
||||
// 引用父类静态带参方法,只能获取到父类类型
|
||||
final Class<Entity<?>> staticSuperFunctionClass = LambdaUtil.getRealClass(MyTeacher::takeId);
|
||||
Assert.assertEquals(Entity.class, staticSuperFunctionClass);
|
||||
|
||||
// 引用静态无参方法,能够获取到正确的类型
|
||||
final Class<MyTeacher> staticSupplierClass = LambdaUtil.getRealClass(MyTeacher::takeAge);
|
||||
Assert.assertEquals(MyTeacher.class, staticSupplierClass);
|
||||
// 引用父类静态无参方法,能够获取到正确的参数类型
|
||||
final Class<MyTeacher> staticSuperSupplierClass = LambdaUtil.getRealClass(MyTeacher::takeIdBy);
|
||||
Assert.assertEquals(MyTeacher.class, staticSuperSupplierClass);
|
||||
Stream.<Runnable>of(() -> {
|
||||
// 引用特定类型的任意对象的实例方法
|
||||
final Func1<MyTeacher, String> lambda = MyTeacher::getAge;
|
||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||
}, () -> {
|
||||
// 枚举测试,不会导致类型擦除
|
||||
final Func1<LambdaKindEnum, Integer> lambda = LambdaKindEnum::ordinal;
|
||||
Assert.assertEquals(LambdaKindEnum.class, LambdaUtil.getRealClass(lambda));
|
||||
}, () -> {
|
||||
// 调用父类方法,能获取到正确的子类类型
|
||||
final Func1<MyTeacher, ?> lambda = MyTeacher::getId;
|
||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||
}, () -> {
|
||||
// 引用特定对象的实例方法
|
||||
Func0<String> lambda = myTeacher::getAge;
|
||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||
}, () -> {
|
||||
// 枚举测试,只能获取到枚举类型
|
||||
Func0<Integer> lambda = LambdaKindEnum.REF_NONE::ordinal;
|
||||
Assert.assertEquals(Enum.class, LambdaUtil.getRealClass(lambda));
|
||||
}, () -> {
|
||||
// 调用父类方法,只能获取到父类类型
|
||||
VoidFunc0 lambda = myTeacher::getId;
|
||||
Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda));
|
||||
}, () -> {
|
||||
// 引用静态带参方法,能够获取到正确的参数类型
|
||||
Func1<MyTeacher, String> lambda = MyTeacher::takeAgeBy;
|
||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||
}, () -> {
|
||||
// 引用父类静态带参方法,只能获取到父类类型
|
||||
Func0<?> lambda = MyTeacher::takeId;
|
||||
Assert.assertEquals(Entity.class, LambdaUtil.getRealClass(lambda));
|
||||
}, () -> {
|
||||
// 引用静态无参方法,能够获取到正确的类型
|
||||
Func0<String> lambda = MyTeacher::takeAge;
|
||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||
}, () -> {
|
||||
// 引用父类静态无参方法,能够获取到正确的参数类型
|
||||
Func1<MyTeacher, ?> lambda = MyTeacher::takeIdBy;
|
||||
Assert.assertEquals(MyTeacher.class, LambdaUtil.getRealClass(lambda));
|
||||
}).forEach(Runnable::run);
|
||||
}
|
||||
|
||||
@Data
|
||||
|
Reference in New Issue
Block a user