Javassist: инициализация поля статического класса заданным значением?

Я хотел бы привязать экземпляр объекта к классу, созданному с помощью Javassist. Этот объект считывается из какого-то источника, данные заранее неизвестны.

    // Create the class.
    CtClass subClass = pool.makeClass( fullName );
    final CtClass superClass = pool.get( Foo.class.getName() );
    subClass.setSuperclass( superClass );

    // Add a static field containing the definition. // Probably unachievable.
    final CtClass defClass = pool.get( SomeMetaData.class.getName() );
    CtField defField = new CtField( defClass, "DEF", subClass );
    defField.setModifiers( Modifier.STATIC );
    subClass.addField( CtField.Initializer.??? );

    return subClass.toClass();

Но когда я проверил API, кажется, что Javassist создает настоящий байт-код, который сохраняет инициализацию в терминах «вызвать это», «создать экземпляр того» или «использовать эту константу».

Есть ли способ попросить Javassist добавить статическое поле, инициализированное существующим экземпляром, заданным во время выполнения?


person Ondra Žižka    schedule 25.06.2013    source источник


Ответы (1)


Вы можете указать инициализатор следующим образом:

// Create the class.
CtClass subClass = pool.makeClass( fullName );
final CtClass superClass = pool.get( Foo.class.getName() );
subClass.setSuperclass( superClass );

// Add a static field containing the definition. // Probably unachievable.
final CtClass defClass = pool.get( SomeMetaData.class.getName() );
CtField defField = new CtField( defClass, "DEF", subClass );
defField.setModifiers( Modifier.STATIC );
subClass.addField( defField, CtField.Initializer.byNew(defClass) );

return subClass.toClass();

Это эквивалентно созданию следующего

class fullName extends Foo {
    static SomeMetaData DEF = new SomeMetaData();
}
person sabertiger    schedule 26.06.2013
comment
Мне нужен не new SomeMetaData(), а данный экземпляр, то есть некоторая ссылка на существующий объект. - person Ondra Žižka; 26.06.2013
comment
Это зависит от того, что вы пытаетесь сделать. Экземпляры объекта класса не могут быть обнаружены во время выполнения, кроме как через интерфейс отладки. Но вы все равно можете передать экземпляр через статический initializer.ie. общедоступный статический _init (SomeMetaData inst) {}. или заводским методом. т.е. статический SomeMetaData DEF = SomeMetaDataFactory.get(). - person sabertiger; 26.06.2013
comment
На самом деле, фабричный метод мог бы работать - я мог бы установить статическое поле некоторого класса, предназначенное исключительно для этой цели, и инициализировать поле нового класса byCall(). Попытаюсь. Спасибо. - person Ondra Žižka; 26.06.2013