Я пытаюсь реализовать это:
@Override // java.util.Function
public Object apply(final ThingWithParameters thing) {
return bozo(thing.getParameters());
}
private Object bozo(final Object[] parameters) {
// Use magic ByteBuddy stuff to "spread" the parameters out
return this.object.baz(parameter0, parameter1); // ...where these are the first two parameters in the array
}
Я пробовал:
builder = builder
.defineMethod("bozo" ...)
.implement(MethodCall.invoke(bazDescription)
.onField(thisObjectFieldDescription)
.withArgumentArrayElements(0, 2))
.implement(parameterizedTypeFunctionThingWithParametersObject) // Function<ThingWithParameters, Object>
.intercept(MethodCall.invoke(bozoDescription) // implement apply(ThingWithParameters thing): call bozo()...
.withMethodCall(MethodCall.invoke(getParametersMethodDescription) // ...with the result of invoking getParameters()...
.onArgument(0))); // ...on thing (except see below)
… но это не работает. Сообщение об ошибке очень странное и заставляет меня думать, что аргумент 0
относится не к thing
, а совсем к чему-то другому (может быть, тип получателя каким-то образом?). Вот фрагмент из стека:
java.lang.IllegalStateException: Cannot invoke public java.lang.Object[] com.foo.ThingWithParameters.getParameters() on java.util.function.Function<? super V, ? extends com.foo.ThingWithParameters>
at net.bytebuddy.implementation.MethodCall$TargetHandler$ForMethodParameter$Resolved.toStackManipulation(MethodCall.java:2530)
at net.bytebuddy.implementation.MethodCall$Appender.toStackManipulation(MethodCall.java:3548)
at net.bytebuddy.implementation.MethodCall$ArgumentLoader$ForMethodCall.toStackManipulation(MethodCall.java:1687)
at net.bytebuddy.implementation.MethodCall$Appender.toStackManipulation(MethodCall.java:3545)
at net.bytebuddy.implementation.MethodCall$Appender.apply(MethodCall.java:3509)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:708)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:693)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:600)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:5660)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2166)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:232)
Обратите внимание, что, хотя мой прокси-класс фактически реализует Function
, он фактически реализует Function<ThingWithParameters, Object>
. И я никогда не определяю V
. Я предполагаю, что ByteBuddy делает это где-то внутри.
Какой рецепт мне следует использовать?