Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将构造函数参数绑定到实例字段?_Java_Byte Buddy - Fatal编程技术网

Java 如何将构造函数参数绑定到实例字段?

Java 如何将构造函数参数绑定到实例字段?,java,byte-buddy,Java,Byte Buddy,是否可以在类上创建新的final字段,并使用在类实例化时设置为该final字段的参数创建构造函数?我尝试了几种方法并寻找答案,但没有找到如何做到这一点的例子 我现在所拥有的: Class proxyClass = new ByteBuddy().subclass(Object.class).implement((Type[]) interfaces) .defineField("dispatcherInvocationHandler", ByteB

是否可以在类上创建新的final字段,并使用在类实例化时设置为该final字段的参数创建构造函数?我尝试了几种方法并寻找答案,但没有找到如何做到这一点的例子

我现在所拥有的:

Class proxyClass = new ByteBuddy().subclass(Object.class).implement((Type[]) interfaces)
                        .defineField("dispatcherInvocationHandler", ByteBuddyDispatcherInvocationHandler.class, Modifier.PRIVATE + Modifier.FINAL)
                        .defineConstructor(Modifier.PUBLIC)
                        .withParameter(ByteBuddyDispatcherInvocationHandler.class)
                        .intercept(MethodCall.invokeSuper().andThen(/* copy argument to field */))
                        .method(ElementMatchers.any())
                        .intercept(InvocationHandlerAdapter.toField("dispatcherInvocationHandler"))
                        .make()
                        .load(BytebuddyProxyGenerator.class.getClassLoader())
                        .getLoaded();
我不想将字段公开,也不想使用setter/getter为该字段创建属性。我想以这样的方式结束:

public class DontCare {
    private final ByteBuddyDispatcherInvocationHandler dispatcherInvocationHandler;

    public DontCare(ByteBuddyDispatcherInvocationHandler arg) {
       super();
       this.dispatcherInvocationHandler = arg;
    }
}
有什么简单的方法可以做到这一点吗

于2016年10月31日更新

最后,在Rafael和ByteBuddy库的1.5.2版本的帮助下,我让它开始工作。工作代码如下:

Class proxyClass = new ByteBuddy().subclass(Object.class).implement((Type[]) interfaces)
                        .defineField("dispatcherInvocationHandler", ByteBuddyDispatcherInvocationHandler.class, Modifier.PRIVATE + Modifier.FINAL)
                        .defineConstructor(Modifier.PUBLIC)
                        .withParameter(ByteBuddyDispatcherInvocationHandler.class)
                        .intercept(
                                MethodCall.invoke(Object.class.getConstructor())
                                        .onSuper()
                                        .andThen(
                                                FieldAccessor.ofField("dispatcherInvocationHandler")
                                                        .setsArgumentAt(0)
                                        )
                        )
                        .method(ElementMatchers.any())
                        .intercept(InvocationHandlerAdapter.toField("dispatcherInvocationHandler"))
                        .make()
                        .load(ByteBuddyProxyGenerator.class.getClassLoader())
                        .getLoaded();

不幸的是,目前没有好办法。然而,我确实将此作为重构
FieldAccessor
实现的灵感,该实现现在允许您执行以下操作:

builder.defineField("desiredField", 
          DispatcherInvocationHandler.class, 
          Visibility.PRIVATE, FieldManifestation.FINAL)
       .defineConstructor(Visibility.PUBLIC)
       .withParameters(String.class)
       .intercept(MethodCall.invokeSuper() // Given such a constructor exists
         .andThen(FieldAccessor.ofField("desiredField").setsArgumentAt(0)))
       .make()
       .load(BytebuddyProxyGenerator.class.getClassLoader())
       .getLoaded();
当您定义这样一个显式setter时,插装本身也变得可链接。因此,您可以设置多个字段,例如:

FieldAccessor.ofField("foo")
             .setsArgumentAt(0)
             .andThen(FieldAccessor.ofField("bar").setsArgumentAt(1));
通过上述实现,构造函数(或任何方法)的实现类似于:

class Sample {
  Object foo, bar;
  Sample(Object a1, Object a2) {
    foo = a1;
    bar = a2;
  }
}

这个附加API是用Byte Buddy 1.5.2发布的。

很遗憾,我遇到了异常:
java.lang.IllegalStateException:public net.bytebuddy.rename.java.lang.Object$bytebuddy$8eiOi2jB(com.fg.generation.specific.bytebuddy.bytebuddy DispatcherInhibicationHandler)没有接受0个参数
我试图调试它,但是没有可能的方法添加。所有参数都接近FieldAccessor代码。我做错了什么吗?我已经更新了前一个问题中的示例-它反映了我现在的代码。我假设它来自超级方法调用。什么是超类?它需要什么构造函数?如果您支持对象,请更改MethodCall以调用对象默认构造函数。非常感谢,它可以工作!虽然我不太清楚MethodCall.invokeSuper()和Method.invoke(构造函数).onSuper()之间的区别。我天真地认为,在这种情况下,invokeSuper()变量将调用超级对象上的默认构造函数。但更深入地思考,invokeSuper()没有重载变量来传递参数,因此不可能处理其他可能的情况(例如调用其他参数化构造函数)。Invoke super调用直接超级方法(如果存在),使用与插入指令的方法相同的参数。我将努力改进文档。很高兴它起作用了!