提问者:小点点

Byte Buddy实例化不带构造函数参数的类


我试图实例化一个没有空参数构造函数的类(它的直接父类也没有空参数构造函数)

Class<?> newClass = new ByteBuddy();
            .subclass(BufferedImage.class)
            ...
            .make()
            .load(BufferedImage.class.getClassLoader())
            .getLoaded();
BufferedImage bufferedImage = dynamicTypeBufferedImage.getConstructor().newInstance();

我想知道这是否可以使用字节伙伴。目前我收到一个错误,说找不到代理类的 getConstructor(),这是有意义的,因为空参数构造函数不存在。有没有办法定义空参数构造函数,以便此实例化起作用?

我试过了:

...
.constructor(any()).intercept(to(new Object() {
    public void construct() throws Exception {
        System.out.println("CALLING XTOR");
    }
 }).andThen(SuperMethodCall.INSTANCE)) // This makes the difference!
...

它来自这里,并给了我Image类没有<code>super()</code>(这是BufferedImage的父类)的错误。

我也试过:

...
.defineConstructor(Visibility.PUBLIC)
.intercept(MethodCall
           .invoke(superClass.getDeclaredConstructor())
           .onSuper())
...

来自这里

最后,我还尝试了.subclass(type,ConstructorStrategy.Default.IMITATE_SUPER_CLASS)来模仿超类,但这似乎没有添加一个空的参数构造函数。

我想要的这个功能模仿了cglib使用增强器实例化其对象的方式。我从我所读到的内容中知道,字节伙伴应该让用户决定如何实例化。我想知道是否有一种简单的方法来将默认实例化设置为空参数构造函数,因为我不关心在类中设置字段,而只是想控制方法空间?


共1个答案

匿名用户

定义一个不以某种方式(直接或通过另一个构造函数)调用其超级构造函数的Java构造函数是不合法的,因为它不能用字节码表示,也不能用byte Buddy表示。

你能做的是:

    < li >不要使用< code>ConstructorStrategy一起定义构造函数。Default.NO_CONSTRUCTORS。 < li >使用Objenesis之类的库来实例化类。

但是请注意,Objenesis使用的是不安全的API,可能在未来的 Java 版本中不受支持。