简体   繁体   中英

Is it possible to create an anonymous class while using reflection?

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.

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];
      }
};

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).

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.)

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