Lai*_*son 5 java methodhandle byte-buddy
我正在利用ByteBuddy 对 Constant 的MethodHandle支持的支持。
我正在尝试(有效地)查找MethodHandle一个类,然后从 ByteBuddy 生成的子类中使用它。
(我知道我可以使用静态来做到这一点MethodHandle字段和类型初始值设定项来完成此操作,但我想使用此常量支持来尝试它。)
我有一个FieldDescription.Token代表第一类的领域,还有一个TypeDescription代表第一类。从这些我可以得到FieldDescription.InDefinedShape这样的:new FieldDescription.Latent(typeDescription, fieldDescriptionToken)。从中我可以得到这样的信息:JavaConstant.MethodHandleJavaConstant.MethodHandle.ofSetter(fieldDescriptionLatent)。这很好用。
然后我这样做:
\n// Call invokeExact() on the MethodHandle I looked up, but\n// call it on that MethodHandle as a constant pool entry.\nbuilder\n .intercept(MethodCall.invoke(INVOKE_EXACT)\n .on(new JavaConstantValue(javaConstantMethodHandle),\n MethodHandle.class)\n // etc.\nRun Code Online (Sandbox Code Playgroud)\n通过这样做,我使用了on采用 a 的重载StackManipulation,在本例中是JavaConstantValue包装 a 的重载JavaConstant,a 是 的超类JavaConstant.MethodHandle。正如你所看到的,我试图呼吁invokeExact()这MethodHandle一点MethodHandle存储为常量。
我的第一个问题是:这是正确的食谱吗?
\n接下来,我将使用这个“字段设置器”在超类中设置的(愚蠢的)字段MethodHandle被命名fortyTwo并且具有以下类型Integer. 您可能会猜到我想将其值设置为什么。这一切都很好,显然与 ByteBuddy 没有任何关系,但它会的。
一切编译都很好。
\n当我运行我的代码时,在我有机会做任何事情之前,即在类加载期间,我得到了ClassFormatErrorByteBuddy 生成的生成子类。该错误抱怨这个子类尝试定义具有无效签名的字段(!):
java.lang.ClassFormatError: Field "fortyTwo" in class com/foo/bar/GeneratedSubclassOf$com$foo$bar$Baz$26753A95 has illegal signature "V"\nRun Code Online (Sandbox Code Playgroud)\n我没有定义这样一个字段。当然,超类确实如此(见上文),并且如前所述,其类型是java.lang.Integer。该字段的访问级别并不重要。
我已经查看了TypeDescription包含的内容DynamicType.Unloaded(显然在加载之前),并且没有fieldTokens,即 ByteBuddy 确实没有尝试在子类中实际定义字段。看来我正在使用的配方中的某些内容使它看起来像是\xe2\x80\xa6uh,验证者?我猜?真的不知道吗?MethodHandle常量所表示的 正在尝试操作子类上的字段,当然不存在这样的字段(我猜测“ V”是 的字节码签名void,并且可能是默认值)。
所以我的最后一个问题是:为什么使用字段设置常量使它看起来像MethodHandle在这种情况下试图在子类中定义字段? 就好像在定义或存储常量或其他操作时删除字段的所属类型一样。
我认为这都与 ByteBuddy 如何支持常量有关MethodHandle。难道ByteBuddy没有MethodHandle在常量池中正确表示这种常量?或者这是某种固有的问题(也许只是字段设置)MethodHandle或者这是(也许只是字段设置)本身的
我确实注意到有问题的 ByteBuddy 代码中有(间接)引用void。这对我来说有一定的意义:如果您要合成一个设置字段的方法句柄,那么它的返回类型将是void。我想知道(na\xc3\xafvely)这实际上是否是在这里传递的正确类型,或者这是否可能靠近问题所在。
另一方面,为了解析(在本例中)是“字段设置器”的方法句柄常量,或类型 1 到 4(包括 1 和 4)的方法句柄,解析必须根据 JVM\' 进行s 场解析规则。这些规则似乎(对于这个 na\xc3\xafve 读者)表明所使用的描述符应该是字段的描述符。相反,我认为ByteBuddy使用的是合成方法句柄的描述符,在本例中为V(或void)。我的 na\xc3\xafve 阅读让我认为至少在“字段设置器”的情况下,返回值getDescriptor()应该是返回值中存在的唯一参数的类型getParameterTypes()。
如果我误诊了,我深表歉意;我仍在学习。
\n| 归档时间: |
|
| 查看次数: |
214 次 |
| 最近记录: |