java如何在第一个MethodCall的第一个参数上使用另一个MethodCall调用MethodCall?
我正试图实现这一点:
@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在内部某个地方这样做
我应该用什么配方
# 1 楼答案
Function
类定义了多个方法,其中一些是默认方法。Byte Buddy将尝试通过Implementation
实现所有这些方法,它对apply
方法有效,但对其他方法无效。因此,应该定义一个显式匹配器来指示要实现的方法