如何在第一个 MethodCall 的第一个参数上调用一个 MethodCall 和另一个 MethodCall?
How do I invoke a MethodCall with another MethodCall on the first MethodCall's first argument?
我正在尝试实现这个:
@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)
请注意,虽然我的代理 class 实际上实现了 Function
,但它实际上实现了 Function<ThingWithParameters, Object>
。而且,我从不定义 V
。我假设 ByteBuddy 在内部某处执行此操作。
我应该使用什么食谱?
Function
class 定义了多种方法,其中一些是默认方法。 Byte Buddy 将尝试通过您的 Implementation
实现所有这些方法,其中它适用于 apply
方法,但对其他方法无效。因此,不如定义一个显式匹配器来指示您要实现的方法。
我正在尝试实现这个:
@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)
请注意,虽然我的代理 class 实际上实现了 Function
,但它实际上实现了 Function<ThingWithParameters, Object>
。而且,我从不定义 V
。我假设 ByteBuddy 在内部某处执行此操作。
我应该使用什么食谱?
Function
class 定义了多种方法,其中一些是默认方法。 Byte Buddy 将尝试通过您的 Implementation
实现所有这些方法,其中它适用于 apply
方法,但对其他方法无效。因此,不如定义一个显式匹配器来指示您要实现的方法。