Можно ли создать анонимный класс при использовании отражения? - PullRequest
7 голосов
/ 24 февраля 2011

Я хотел бы иметь возможность реализовать метод во время выполнения, который вызывается до того, как объект запускает инициализаторы.Это позволит мне установить поля, которые используются во время инициализации.

Вот пример:

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

Я, вероятно, в конечном итоге буду использовать аспекты, но я хотел бы знать, существует ли чистый способ Java.

Ответы [ 3 ]

1 голос
/ 24 февраля 2011

Звучит так, как вы хотите: Динамические прокси , доступные с Java 1.3.

Редактировать: Я посмотрел на mockito чтобы увидеть, как им удалось смоделировать конкретные классы, и оказалось, что они создают байт-код, а затем загружают его загрузчиком классов.Мало того, что это не совсем то, что вы хотите, но и более сложное, чем это необходимо.

Я согласен со Стивеном С. Почему вы хотите это сделать?Я подозреваю, что может быть более легкий путь.Я подозреваю, что вам лучше подойдет шаблон Strategy или Command .В этом случае пользовательский код находится в своем собственном маленьком классе:

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

, который либо назначается основному классу, либо оборачивает основной класс (в зависимости от необходимости).

1 голос
/ 24 февраля 2011

То, что вы пытаетесь сделать, повлечет за собой создание нового анонимного внутреннего класса, который является подклассом некоторого класса, который вы знаете только во время выполнения. Отражение не может решить эту проблему.

Динамические прокси могут ... если вы пытаетесь реализовать динамически загружаемый интерфейс.

Единственные другие подходы, которые я могу придумать, - это использовать BCEL или динамическую генерацию / компиляцию исходного кода. И оба будут очень сложными. И ни один не считается чистой Явой.

Мой совет - по-новому взглянуть на то, чего вы пытаетесь достичь. (Ваш вопрос не дает никаких намеков относительно того, что это может быть, поэтому трудно предложить какие-либо практические предложения.)

1 голос
/ 24 февраля 2011

Вы имеете в виду что-то вроде этого, предполагая, что оно скомпилируется (чего не происходит):

@Override
A a = aClass.newInstance()
{
  public void initialize() {
        this.message = args[1];
      }
};
...