我想生成一个类的字节代码,它将一个方法引用作为参数传递给另一个方法。例如:
public class GeneratedClass {
public GeneratedClass() {
Test.foo((Function)Test::getId)
}
}使用ByteBuddy,我可以生成一个带有自定义构造函数的类,并创建一个InvokeDynamic来表示Test::getId,但问题是我不能将InvokeDynamic作为参数传递给我的MethodCall。我目前的实现如下:
var fooMethod = Test.class.getMethod("foo",Function.class);
InvokeDynamic methodRef = InvokeDynamic.lambda(Test.class.getMethod("getId"), Function.class)
.withoutArguments();
new ByteBuddy()
.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
.name("GeneratedClass")
.defineConstructor(Visibility.PUBLIC)
.intercept(
MethodCall.invoke(fooMethod)
.with((Object)null) \\I want to pass the methodRef instead of null
.andThen(methodRef)
).make()
.saveIn(new File("target"));这将生成以下内容:
public class GeneratedClass {
public GeneratedClass() {
Test.foo((Function)null);
Test::getId;
}
}发布于 2021-05-11 15:38:55
到目前为止,领域特定语言还不支持这一点,但是您可以向with提供一个自定义的StackManipulation作为参数。在您的例子中,您需要为此解析一个MethodInvocation。
通过一个小技巧,您现在就可以实现这一点,但要创建一个helper方法:
builder = builder
.defineMethod("mylambda", Function.class, Visibility.PRIVATE, Ownership.STATIC)
.intercept(methodRef)然后,您可以使用MethodCall调用此方法并将其作为参数传递。
https://stackoverflow.com/questions/67476142
复制相似问题