返回子类型时是否需要 Assigner.Typing.DYNAMIC 分配器?
Is an Assigner.Typing.DYNAMIC Assigner required when returning a subtype?
假设我想通过做一些非常愚蠢的事情来实现 Function<Object, Object>
接口:
final ParameterizedType whatTheUserWillSee = functionObjectObject(); // e.g. Function<Object, Object>
DynamicType.Builder<?> builder = builder
.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
.merge(Visibility.PUBLIC, SyntheticState.SYNTHETIC, TypeManifestation.FINAL)
.defineConstructor(Visibility.PUBLIC, SyntheticState.SYNTHETIC)
.intercept(MethodCall.invoke(OBJECT_CONSTRUCTOR).onSuper()) // OBJECT_CONSTRUCTOR is just new Object()
.implement(whatTheUserWillSee)
.intercept(MethodCall.invoke(new MethodDescription.ForLoadedMethod(Object.class.getMethod("toString"))
.withAssigner(Assigner.DEFAULT, Assigner.Typing.DYNAMIC));
也就是说,我正在创建这样的东西:
public Foo() {
super();
}
public Object apply(Object x) {
return toString();
}
没有 .withAssigner
调用,我得到:
java.lang.IllegalStateException: Cannot return class java.lang.String from public java.util.function.Function java.util.function.Function.compose(java.util.function.Function)
at net.bytebuddy.implementation.MethodCall$TerminationHandler$Simple.toStackManipulation(MethodCall.java:3005)
at net.bytebuddy.implementation.MethodCall$Appender.toStackManipulation(MethodCall.java:3551)
at net.bytebuddy.implementation.MethodCall$Appender.apply(MethodCall.java:3509)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:708)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:693)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:600)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:5660)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2166)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:232)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:204)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3595)
我不是 ByteBuddy 内部专家。为什么需要动态类型分配器才能 return Object
的子类型?
您正在拦截 Function
的所有方法。当你认为你在拦截 apply 时,如果你仔细看,字节好友正在抱怨 compose
方法。指定一个明确的匹配器来避免这种情况。
假设我想通过做一些非常愚蠢的事情来实现 Function<Object, Object>
接口:
final ParameterizedType whatTheUserWillSee = functionObjectObject(); // e.g. Function<Object, Object>
DynamicType.Builder<?> builder = builder
.subclass(Object.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
.merge(Visibility.PUBLIC, SyntheticState.SYNTHETIC, TypeManifestation.FINAL)
.defineConstructor(Visibility.PUBLIC, SyntheticState.SYNTHETIC)
.intercept(MethodCall.invoke(OBJECT_CONSTRUCTOR).onSuper()) // OBJECT_CONSTRUCTOR is just new Object()
.implement(whatTheUserWillSee)
.intercept(MethodCall.invoke(new MethodDescription.ForLoadedMethod(Object.class.getMethod("toString"))
.withAssigner(Assigner.DEFAULT, Assigner.Typing.DYNAMIC));
也就是说,我正在创建这样的东西:
public Foo() {
super();
}
public Object apply(Object x) {
return toString();
}
没有 .withAssigner
调用,我得到:
java.lang.IllegalStateException: Cannot return class java.lang.String from public java.util.function.Function java.util.function.Function.compose(java.util.function.Function)
at net.bytebuddy.implementation.MethodCall$TerminationHandler$Simple.toStackManipulation(MethodCall.java:3005)
at net.bytebuddy.implementation.MethodCall$Appender.toStackManipulation(MethodCall.java:3551)
at net.bytebuddy.implementation.MethodCall$Appender.apply(MethodCall.java:3509)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:708)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:693)
at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:600)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:5660)
at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2166)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:232)
at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:204)
at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3595)
我不是 ByteBuddy 内部专家。为什么需要动态类型分配器才能 return Object
的子类型?
您正在拦截 Function
的所有方法。当你认为你在拦截 apply 时,如果你仔细看,字节好友正在抱怨 compose
方法。指定一个明确的匹配器来避免这种情况。