Byte Buddy создает экземпляр класса без параметров для конструктора - PullRequest
0 голосов
/ 23 мая 2018

Я пытаюсь создать экземпляр класса, у которого нет пустого конструктора параметров (и у его прямого родителя также нет пустого конструктора параметров)

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 не имеет super() (который является родительским классом BufferedImage).

Я также пытался:

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

, который пришел от здесь

Наконец, я также попробовал .subclass(type, ConstructorStrategy.Default.IMITATE_SUPER_CLASS); способ имитировать суперкласс, но, похоже, он не добавляет пустой конструктор параметров.

Эта функциональность, которую я хочу, имитирует способ, которым cglib создает его экземпляробъекты, использующие энхансер.Из того, что я читал, я знаю, что байтовый компаньон должен позволять пользователю решать, как создать экземпляр.Мне было интересно, есть ли простой способ просто установить экземпляр по умолчанию для пустого конструктора параметров, так как я не забочусь о настройке полей в классе, а просто хочу управлять пространством метода?

1 Ответ

0 голосов
/ 23 мая 2018

Недопустимо определять Java-конструктор, который каким-либо образом не вызывает своего супер-конструктора (напрямую или через другой конструктор), поскольку он не может быть выражен в байтовом коде, это не может быть сделано в Byte Buddy.

Что вы можете сделать:

  1. Не определять конструктор целиком, используя ConstructorStrategy.Default.NO_CONSTRUCTORS.
  2. Использовать библиотеку типа Objenesis для создания экземпляра класса.

Обратите внимание, однако, что Objenesis использует небезопасный API, который может не поддерживаться в будущей версии Java.

...