I've got the following two methods:
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(); }
including the following two interfaces:
@FunctionalInterfacepublic interface IGetter<T, R>{ @Nullable R get( T object );}@FunctionalInterfacepublic interface ISetter<T, I>{ void set( T object, @Nullable I value );}
This works great for all Class-Types, including the Number-Wrappers for primitive types such as Integer
for int
. However, if I have a setter that takes an int
or a getter that returns an ìnt
, it tries passing / returning the Number-Wrapper, resulting in an exception.
What's the correct way to box / unbox this without having to make another method. The reason here is to keep the API clean and simple to use. I am willing to take a small performance hit for the boxing / unboxing here.