繁体   English   中英

创建新对象的 ByteBuddy 方法实现

[英]ByteBuddy method implementation that creates a new object

我正在使用 Byte Buddy 1.9.0 作为基于 Xtext 的编程语言的代码生成器,并且我正在努力为实例化“匿名”类的方法生成字节码。 出于所有意图和目的,我试图让 Byte Buddy 创建一个方法,该方法与此等效:

package fxxx.test;
class DummyUser
{
  DummyOperator dummy()
  {
    return new DummyUser$1();
  }
}

我的编译器已经创建了嵌套的“匿名”类DummyUser$1 ,但是,对于我的一生,我无法提出正确的 Byte Buddy 指令序列来创建该类的新对象,然后返回该对象。 经过一番搜索,我遇到了MethodCall.construct(MethodDescription) ,但我当前的代码只产生以下异常:

java.lang.IllegalStateException: Cannot return void from public fxxx.test.DummyOperator fxxx.test.DummyUser_.dummy()
    at net.bytebuddy.implementation.MethodCall$TerminationHandler$1.resolve(MethodCall.java:2189)
    at net.bytebuddy.implementation.MethodCall.toStackManipulation(MethodCall.java:2405)
    at net.bytebuddy.implementation.MethodCall$Appender.apply(MethodCall.java:2434)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:698)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:683)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:590)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:5114)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1915)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:197)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:174)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3376)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:3565)
...

这个错误似乎告诉我,有点可以理解,因为该类的构造函数具有<init>()V签名并且从技术上讲返回void这等效于从应该真正返回DummyOperator某个子类的方法返回一个void值。 我试图结合MethodCall.constructStackManipulation是复制了堆栈的顶部,但随着TypeCreation通过new字节码已经被烤成MethodCall.construct我似乎没有能够获得新创建的原始对象实例. 该项目尚未开源,但我可以提供这个片段(使用 Xtend 语法)来说明我的代码正在做什么:

    val Builder<?> anonymousClass = ... // the anonymous class that has already been created
    val TypeDescription declaringType = describe(anonymousClass) // basically .make.typeDescription
    val MethodDescription constructor = method(declaringType, new TypeDescription.ForLoadedType(void), "<init>", #[]) // new Latent declaringType/returnType
    val MethodCall construct = MethodCall.construct(constructor)
    // ^^^ this value gets return as the new method's Implementation

我缺少什么以便该方法正确返回新创建的实例?

所以,看起来我毕竟没有遗漏任何步骤,或者必然对对象实例化本身做错了什么。 当我在调试器中运行这个时,我注意到无效的堆栈操作是由类型不匹配引起的,这表明方法的返回类型实际上与匿名类的类型不兼容(我的错误;语言的类型系统比简单的 Java 稍微复杂一些,并且这两种类型以微妙的方式不兼容)。 我猜,学到的教训是在遇到上述异常时仔细检查类型兼容性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM