我正在尝试生成具有循环类依赖性的类,类似于这个问题:
Byte Buddy – Handling cyclic references in generated classes
作为一个最小的例子,我想要生成的类有这样的依赖:
- //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",null,null);
- final TypeDescription.Latent typeDescrB = new TypeDescription.Latent("B",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();
- }
- }
- }
当我运行它时,我在线程“main”中得到Exception java.lang.IllegalStateException:无法解析潜在类型描述的声明类型:标记行中的类B.
上面提到的问题的答案是“确保在正确定义潜在类型之前不加载类型”,我猜这可能是我的问题.我不知道如何定义潜在类型虽然:-(
编辑:将A和B类放在最后(因为这将是理想的解决方案)
编辑:添加堆栈跟踪
- 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)