【发布时间】:2021-09-18 22:22:46
【问题描述】:
我有以下两种方法:
public static <T, R> IGetter<T, R> createGetterViaMethodname( final Class<T> clazz, final String methodName,
final Class<R> fieldType )
throws Throwable
{
final MethodHandles.Lookup caller = MethodHandles.lookup();
final MethodType methodType = MethodType.methodType( fieldType );
final MethodHandle target = caller.findVirtual( clazz, methodName, methodType );
final MethodType type = target.type();
final CallSite site = LambdaMetafactory.metafactory(
caller,
"get",
MethodType.methodType( IGetter.class ),
type.erase(),
target,
type );
final MethodHandle factory = site.getTarget();
return (IGetter<T, R>) factory.invoke();
}
public static <T, I> ISetter<T, I> createSetterViaMethodname( final Class<T> clazz, final String methodName,
final Class<I> fieldType )
throws Throwable
{
final MethodHandles.Lookup caller = MethodHandles.lookup();
final MethodType methodType = MethodType.methodType( void.class, fieldType );
final MethodHandle target = caller.findVirtual( clazz, methodName, methodType );
final MethodType type = target.type();
final CallSite site = LambdaMetafactory.metafactory(
caller,
"set",
MethodType.methodType( ISetter.class ),
type.erase(),
target,
type );
final MethodHandle factory = site.getTarget();
return (ISetter<T, I>) factory.invoke();
}
包括以下两个接口:
@FunctionalInterface
public interface IGetter<T, R>
{
@Nullable
R get( T object );
}
@FunctionalInterface
public interface ISetter<T, I>
{
void set( T object, @Nullable I value );
}
这适用于所有类类型,包括用于基本类型的数字包装器,例如Integer 用于int。但是,如果我有一个接受 int 的 setter 或一个返回 ìnt 的 getter,它会尝试传递/返回 Number-Wrapper,从而导致异常。
什么是装箱/拆箱的正确方法,而无需使用其他方法。这里的原因是保持 API 干净且易于使用。我愿意为这里的装箱/拆箱带来小小的性能损失。
【问题讨论】:
-
“导致异常”什么异常
标签: java lambda reflection methodhandle lambda-metafactory