4

I'd like to bind some object instance to a class created using Javassist. This object is read from some source, the data are not known upfront.

    // 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();

But as I checked the API, it seems that Javassist creates a real bytecode, which stores initialization in terms of "call this" or "instantiate that" or "use this constant".

Is there a way to ask Javassist to add a static field initialized to an existing instance given at runtime?

Ondra Žižka
  • 43,948
  • 41
  • 217
  • 277

1 Answers1

5

You can specific an initializer like this:

// 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();

This is equivalent to creating the following

class fullName extends Foo {
    static SomeMetaData DEF = new SomeMetaData();
}
sabertiger
  • 428
  • 2
  • 7
  • What I need is not `new SomeMetaData()` but a given instance, i.e. some reference to an existing object. – Ondra Žižka Jun 26 '13 at 14:35
  • It depends on what you're trying to do. Object instances of a class cannot be discovered at runtime except through the debugging interface. But you can still pass the instance via a static initializer.ie. public static _init(SomeMetaData inst) {}. or via a factory method. ie static SomeMetaData DEF = SomeMetaDataFactory.get(). – sabertiger Jun 26 '13 at 16:39
  • Actually, factory method could work - I could set a static field of some class serving solely that purpose, and initialize the new class'es field `byCall()`. Will try. Thanks. – Ondra Žižka Jun 26 '13 at 18:54