gpt4 book ai didi

java - 如何在 ByteBuddy 中安装和使用常量 MethodHandle?

转载 作者:行者123 更新时间:2023-12-03 19:02:45 26 4
gpt4 key购买 nike

我在玩support that ByteBuddy has for constant MethodHandle s .
我正在尝试(有效地)查找 MethodHandle在一个类上,然后从 ByteBuddy 生成的子类中使用它。
(我知道我可以使用静态 MethodHandle 字段和类型初始化器来做到这一点,但我想尝试使用这种常量支持。)
我有一个 FieldDescription.Token表示第一类中的一个字段,以及一个 TypeDescription代表第一类。从这些我可以得到 FieldDescription.InDefinedShape像这样:new FieldDescription.Latent(typeDescription, fieldDescriptionToken) .从中我可以得到 JavaConstant.MethodHandle像这样: JavaConstant.MethodHandle.ofSetter(fieldDescriptionLatent) .这工作正常。
然后我这样做:

// Call invokeExact() on the MethodHandle I looked up, but
// call it on that MethodHandle as a constant pool entry.
builder
.intercept(MethodCall.invoke(INVOKE_EXACT)
.on(new JavaConstantValue(javaConstantMethodHandle),
MethodHandle.class)
// etc.
通过这样做,我正在使用 on overload that takes a StackManipulation ,在这种情况下是 JavaConstantValue它包裹了 JavaConstant ,它是 JavaConstant.MethodHandle 的父类(super class).如您所见,我正在尝试调用 invokeExact()关于这个 MethodHandle MethodHandle希望存储为常数。
我的第一个问题是: 这是正确的食谱吗?
接下来,我将使用这个“字段 setter ” MethodHandle 在父类(super class)中设置的(愚蠢的)字段被命名为 fortyTwo类型为 Integer .您可能会猜到我想将其值设置为什么。 😀 这一切都很好,显然(还)与 ByteBuddy 没有任何关系,但它会的。
一切都编译得很好。
当我运行我的代码时,在我有机会做任何事情之前,即在类加载期间,我得到一个 ClassFormatError对于 ByteBuddy 生成的生成的子类。该错误提示此子类已尝试使用无效签名定义字段(!):
java.lang.ClassFormatError: Field "fortyTwo" in class com/foo/bar/GeneratedSubclassOf$com$foo$bar$Baz$26753A95 has illegal signature "V"
我没有定义这样一个领域。父类(super class)当然可以(见上文),如前所述,它的类型是 java.lang.Integer .字段的访问级别无关紧要。
我看过 TypeDescriptionDynamicType.Unloaded 包含(显然是在加载之前)并且没有 fieldTokens ,即 ByteBuddy 并没有真正尝试在子类中实际定义一个字段。看来我正在使用的配方中的某些东西使它看起来像是……呃,验证者?我猜?真的不知道?该 MethodHandle由常量表示的是试图操纵子类上的字段,当然不存在这样的字段(我猜“ V”是 void的字节码签名,可能是默认值)。
所以我的最后一个问题是: 为什么使用字段设置MethodHandle常量使它看起来像 ByteBuddy 在这种情况下试图在子类中定义一个字段? 就好像在定义或存储常量时删除了该字段的所属类型。
我认为这一切都与 ByteBuddy 如何支持常量 MethodHandle 有关s。可能是 ByteBuddy 没有正确表示这种常量 MethodHandle在常量池中?或者这是某种固有问题(可能只是字段设置) MethodHandle是他们自己吗?
我确实注意到 there is a reference (indirectly) to void in the ByteBuddy code in question .这对我来说有一定的意义:如果你要合成一个设置字段的方法句柄,那么它的返回类型将是 void .不过,我想知道(天真地)这是否实际上是在此处传递的正确类型,或者这是否可能靠近问题所在。
另一方面,似乎为了解析(在这种情况下)是“字段 setter ”或 a method handle of kinds 1 through 4, inclusive的方法句柄常量。 , resolution must proceed according to the JVM's rules of field resolution .那些规则(对于这个天真的读者来说)似乎是 indicate that the descriptor used should be the field's descriptor .相反,我认为 ByteBuddy is using the descriptor of the synthesized method handle在这种情况下是 V (或 void )。我幼稚的阅读使我认为至少在“字段 setter ”的情况下, getDescriptor() 的返回值应该是 getParameterTypes() 的返回值中存在的唯一参数的类型.
如果我误诊了,我深表歉意;我仍在学习。

最佳答案

对于后代:这原来是 ByteBuddy for which I've submitted a PR 中的一个错误.

关于java - 如何在 ByteBuddy 中安装和使用常量 MethodHandle?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64296731/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com