Если вы довольны использованием отражения под капотом, просто не нравится try
/ catch
вокруг invoke
, вы можете просто сделать простую служебную функцию, например:
public static <T> Consumer<T> toConsumer(Object annotated, Method m) {
return param -> {
try {
m.invoke(annotated, param);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
};
}
И это дает вам именно тот синтаксис, который вы хотели:
CALLBACKS_MAPPER.registerCallback(toConsumer(annotated, method));
Но если вы хотите вообще избежать отражения, вы можете использовать LambdaMetafactory
, чтобы создать Consumer
:
static Consumer<String> toConsumer(MethodHandles.Lookup lookup, Object annotated, Method method) throws Throwable {
MethodType consumeString = MethodType.methodType(void.class, String.class);
MethodHandle handle = lookup.unreflect(method);
final CallSite site = LambdaMetafactory.metafactory(lookup, "accept",
MethodType.methodType(Consumer.class, annotated.getClass()),
consumeString.changeParameterType(0, Object.class),
handle,
consumeString);
return (Consumer<String>) site.getTarget().invoke(annotated);
}
Измените String
на то, что ожидается от ваших обратных вызовов.И затем:
CALLBACKS_MAPPER.registerCallback(toConsumer(MethodHandles.lookup(), annotated, method));
Конечно, единственное правильное решение здесь состоит в том, что вы реорганизуете свой код для использования известного интерфейса обратного вызова, на котором вы обычно можете вызывать определенный метод, вместо передачи Method
s вокруг.