简体   繁体   中英

Byte Buddy instantiate class without parameters for constructor

I am trying to instantiate a class that doesn't have an empty parameter constructor (and it's direct parent also doesn't have an empty parameter constructor)

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

I am wondering if this is possible using byte buddy. Currently I am getting an error saying that the getConstructor() of the proxy class is not found which makes sense because the empty parameter constructor doesn't exist. Is there a way to define the empty parameter constructor such that this instantiation works?

I have tried:

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

which came from here and gave me the error of Image class doesn't have super() (which is the parent class of BufferedImage).

I also tried:

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

which came from here

Lastly, I also tried the .subclass(type, ConstructorStrategy.Default.IMITATE_SUPER_CLASS); way to imitate super class but this doesn't seem to add an empty parameter constructor.

This functionality that I want, mimics the way cglib instantiates its objects using the enhancer. I know from what I have been reading that byte buddy is supposed to let the user decide how to instantiate. I was wondering if there was an easy way to just set the default instantiation to the empty parameter constructor since I don't care about setting fields in the class but rather just want to control the method space?

It is not legal to define a Java constructor that does not invoke its super constructor in some way (either directly or via another constructor), since it cannot be expressed in byte code, it cannot be done in Byte Buddy.

What you can do is:

  1. Not define a constructor alltogether using ConstructorStrategy.Default.NO_CONSTRUCTORS .
  2. Use a library like Objenesis to instantiate a class.

Note however that Objenesis is using unsafe API that might not be supported in a future Java version.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM