当前位置: 首页 > 面试题库 >

字节预算:生成具有循环类型的类

终翔
2023-03-14
问题内容

我正在尝试生成具有循环类依赖性的类,类似于此问题:字节好友-处理生成的类中的循环引用

作为最小的示例,我要生成的类的种类具有如下依赖性:

//class A depends on class B, and vice-versa
final class A { B theB; }
final class B { A theA; }

上面链接中接受的答案没有为我提供足够的信息来使它起作用。这是我尝试的:

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
import net.bytebuddy.jar.asm.Opcodes;

public class ByteBuddyHello {

    public static void main(String[] args) {
        try {
            final ByteBuddy bb = new ByteBuddy();
            final TypeDescription.Latent typeDescrA = new TypeDescription.Latent("A", 0, null, null);
            final TypeDescription.Latent typeDescrB = new TypeDescription.Latent("B", 0, null, null);
            final DynamicType.Unloaded<Object> madeA = bb
                    .subclass(Object.class)
                    .name("A")
                    .defineField("theB", typeDescrB, Opcodes.ACC_PUBLIC)
                    .make(); // exception thrown here!
            final DynamicType.Unloaded<Object> madeB = bb.subclass(Object.class)
                    .name("B")
                    .defineField("theA", typeDescrA, Opcodes.ACC_PUBLIC)
                    .make();

            Object a = madeA
                    .include(madeB)
                    .load(ByteBuddyHello.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
                    .getLoaded().newInstance();
            System.out.println(a.toString());
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

当我运行它时,我进入Exception in thread "main" java.lang.IllegalStateException: Cannot resolve declared type of a latent type description: class B标记行。

上面提到的问题的答案是:“确保在正确定义潜在类型之前,不要加载类型”,我猜这可能是我的问题。我不知道如何定义潜在类型:-(

编辑:使类AB最终以上(因为这将是理想的解决方案)

编辑:添加堆栈跟踪

Exception in thread "main" java.lang.IllegalStateException: Cannot resolve declared type of a latent type description: class B
    at net.bytebuddy.description.type.TypeDescription$Latent.getDeclaringType(TypeDescription.java:7613)
    at net.bytebuddy.description.type.TypeDescription$AbstractBase.getSegmentCount(TypeDescription.java:6833)
    at net.bytebuddy.implementation.attribute.AnnotationAppender$ForTypeAnnotations.onNonGenericType(AnnotationAppender.java:617)
    at net.bytebuddy.implementation.attribute.AnnotationAppender$ForTypeAnnotations.onNonGenericType(AnnotationAppender.java:333)
    at net.bytebuddy.description.type.TypeDescription$Generic$OfNonGenericType.accept(TypeDescription.java:3364)
    at net.bytebuddy.implementation.attribute.FieldAttributeAppender$ForInstrumentedField.apply(FieldAttributeAppender.java:122)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$FieldPool$Record$ForExplicitField.apply(TypeWriter.java:270)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:4156)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1633)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:174)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:155)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:2559)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:2661)
    at my.package.playground.ByteBuddyHello.main(ByteBuddyHello.java:20)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)

问题答案:

这是ByteBuddy中的错误;类型注释的解析器需要知道任何类型描述​​的深度,因此可以解析任何类型描述​​的类型路径。对于潜在类型,此深度始终为0,但默认实现采用更复杂的解决方案。

此问题将在下一版本中修复。 同时,子类化潜在类型描述并重写该方法以返回0。

我决定不更改TypeDescription.Latent类型,而是使InstrumentedType.Default实现更易于访问。使用后一种类型,该类型允许您定义任何用户都可以看到的循环类型的特征。这样,例如,如果要定义Implementation可针对此功能进行验证的,则可以指定现有的字段和方法。



 类似资料:
  • 我想生成一个具有不同节点类型的树。对于每个节点类型,有不同的节点类型组合,可以成为该节点的子节点。任何节点类型都可能没有子节点。 基本上迫使我从一个叶生成器开始,生成一个没有子节点的任何类型的节点,从内到外构建树。从子生成器创建生成器的函数基本上必须生成所需的父节点类型,并在子生成器上使用

  • 当您需要多次执行代码块时,可能会出现这种情况。 通常,语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。 编程语言提供各种控制结构,允许更复杂的执行路径。 循环语句允许我们多次执行一个语句或一组语句,以下是大多数编程语言中循环语句的一般说法 - C ++编程语言提供以下类型的循环来处理循环要求。 Sr.No 循环类型和描述 1 while 循环 在给定条件为真时重复语句或语

  • 将Android Studio升级到4.0版本后,在“gradle-wrapper.properties”中:

  • 我正在寻找一种方法来执行一个给定的有向非加权图上的拓扑排序,其中包含循环。结果不仅要包含顶点的排序,还要包含被给定排序所违背的边集。这组边应是最小的。 由于我的输入图可能很大,我不能使用指数时间算法。如果不可能在多项式时间内计算出最优解,那么对于给定的问题,什么启发式是合理的?

  • 循环是任何编程语言的另一个最重要的方面。 编写程序时,您可能会遇到多次执行相同语句而某些时候可能无限次执行的情况。 有几种方法可以指定进程应该持续多长时间,以及如何停止或以其他方式更改进程。 迭代块可以非正式地称为循环,并且循环中的每个代码执行被称为循环的迭代。 下图显示了一个简单的循环逻辑流程 - Euphoria提供以下三种类型的循环语句 - while statement loop unti

  • 问题内容: 我正在尝试在某些类图中围绕类生成运行时包装,但是当图中有一个循环时,我不知道如何处理这种情况。想象有一个类A的字段类型为B,但是类型B的字段类型为A。我想生成类A’和B’,以便类A’的字段类型为B’,而B’的字段类型为B。 A’类型的字段。在字节伙伴中,方法“ defineField”可以接收类型定义的参数。我认为必须有一种方法可以为尚未定义的类型定义TypeDefinition,但我