8

I would like to be able to implement a method at runtime that is called before an object runs the initializers. This will allow me to set fields that are used during initialization.

Here is an example:

class A {
  public A() {
    initialize();
  }
  public void initialize() { }
}

class B extends A {
  public String message;
  {
    System.out.println(message);
  }
}

public class MainClass {
  public static void main(final String[] args) throws Exception {

    Class<A> aClass = (Class<A>)Class.forName(args[0]);
    // what's next in order to something like this even though
    // I don't know what subclass of A was passed in as an
    // argument above 
    A a = aClass.newInstance()
    {
      public void initialize() {
        this.message = args[1];
      }
    };
  }
}

I will probably end up using aspects, but I would like to know if there is a pure Java way.

Matt
  • 978
  • 10
  • 24
  • Would it be possible for you to enforce a contract by which the c'tor of the dynamic class (be it `B`, or any either derivative) accepts the `message` value as a parameter? If so, you could have the instance created using `aClass.getDeclaredConstructor(String.class).getNewInstance(args[1])`, instead of vanilla `aClass.newInstance()`. WDYT? – d4vidi Jul 28 '22 at 08:26

3 Answers3

1

Do you mean something like this assuming it would compile (which it doesn't):

@Override
A a = aClass.newInstance()
{
  public void initialize() {
        this.message = args[1];
      }
};
user207421
  • 305,947
  • 44
  • 307
  • 483
1

It sounds like what you want are Dynamic Proxies, which have been available since Java 1.3.

Edit: I looked into mockito to see how they managed to mock concrete classes and it turns out they create byte code and then load it with a class loader. Not only does that not really get what you want, but it is more complex than it necessary.

I agree with Stephen C: Why do you want to do this? I suspect there may be an easier way. I suspect what may work better for you is the Strategy or Command pattern. In that case, the custom code is in its own little class:

public class Initializer<A> {

  public (abstract) void initialize(A parent);
}

final String args[] = ...;
Initializer<A> initializer = new Initializer<A>() {
  public void initialize(A parent) {
      parent.setMessage(args);
  }
};

which is either assigned to the main class or wraps the main class (depending on the need).

Kathy Van Stone
  • 25,531
  • 3
  • 32
  • 40
  • I'm not sure how I could implement this since proxies implement interfaces. I need to implement a method of a Class in my case. Could you be more specific? – Matt Feb 24 '11 at 04:15
  • The next step is to look at the code of mockito (http://mockito.org/), as they have code to mock concrete classes, which looks to be similar to what you want. I may be able to help with that over the weekend. – Kathy Van Stone Feb 25 '11 at 15:20
1

What you are trying to do would entail creating a new anonymous inner class that is a subclass of some class that you only know at runtime. Reflection cannot solve this problem.

Dynamic proxies might ... if you were trying to implement a dynamically loaded interface.

The only other approaches I can think of are to use BCEL or dynamic source code generation / compilation. And both are going to be very complicated. And neither count as pure Java.

My advice would be to take a fresh look at what it is you are trying to achieve. (Your question gives no hints as to what that might be, so it is hard to offer any practical suggestions.)

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • I am running methods in the initializers that require the fields to be initialized before the initializers are run. The conceptual is that I am loading a view, the view logic is in the initializer, and I would like to set the model attributes before the view is created. – Matt Feb 24 '11 at 13:08