Java Метапрограммирование - PullRequest
11 голосов
/ 15 января 2012

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

У меня есть класс, который ведет себя примерно так:

class Single
{
    public void doActionA() {}
    public void doActionB() {}
    public void doActionC() {}
}

И затем у меня есть класс SingleList, который действует как коллекция этих классов (в частности, это для библиотеки 2D Sprite, а «действия» - это всевозможные преобразования: вращение, сдвиг, масштабирование и т. Д.). Я хочу иметь возможность сделать следующее:

class SingleList
{
    public void doActionA() {
        for (Single s : _innerList) {
            s.doActionA();
        }
    }

    ... etc ...
}

Есть ли способ просто отложить метод (или известный список методов) для каждого члена внутреннего списка? В любом случае, без необходимости специально перечислять каждый метод, затем проходить через каждый внутренний элемент и применять его вручную?

Чтобы сделать вещи немного сложнее, методы имеют разную арность, но все они возвращаемого типа "void".

1 Ответ

11 голосов
/ 15 января 2012

К сожалению, Java не поддерживает создание классов во время выполнения, и это то, что вам нужно: SingleList необходимо автоматически обновить необходимыми методами-заглушками, чтобы соответствовать классу Single.

Я могуПодумайте о следующих подходах к этому вопросу:

  1. Использование Отражение Java :

    • Плюсы:
      • Это легкодоступны на языке Java, и вы можете легко найти документацию и примеры.
    • Минусы:
      • Класс SingleList не будет совместим с интерфейсом класса Singleбольше.
      • Компилятор Java и любые IDE, как правило, не могут помочь с методами, вызываемыми с помощью отражения - ошибки, которые будут обнаружены компилятором, обычно преобразуются в исключения времени выполнения.
      • В зависимости от вашегоВ случае использования вы также можете увидеть заметное снижение производительности.
  2. Использовать систему сборки вместе с генератором исходного кодадля автоматического создания файла SingleList.java.

    • Плюсы:
      • После того, как вы настроите его, вам больше не придется иметь с ним дело.
    • Минусы:
      • Установка этого имеет определенную степень сложности.
      • Вы должны были бы отдельно убедиться, что класс SingleList загружен в любую JVM - или вашу IDE, для этоговещество - фактически соответствует загруженному Single классу.
  3. Решить эту проблему вручную - создав интерфейс (например, SingleInterface) или базовый рефераткласс для использования обоими классами должен помочь, так как любая приличная IDE будет указывать на невыполненные методы.Правильная архитектура класса позволит минимизировать дублирующийся код, и ваша IDE может помочь с генерацией шаблонных частей.

    • Плюсы:
      • Нет кривой настройки, которую нужно преодолеть.
      • Ваша IDE всегда будет видеть правильный набор классов.
      • Архитектура классов обычно улучшается впоследствии.
    • Минусы:
      • Всеявляется ручным.
  4. Используйте библиотеку генерации байт-кода, такую ​​как Javassist или BCEL для динамической генерации /изменяйте класс SingleList на лету.

    • Плюсы:
      • Этот метод чрезвычайно мощный и может сэкономить много времени в долгосрочной перспективе.
    • Минусы:
      • Использование библиотек генерации байт-кода обычно не тривиально и не для слабонервных.
      • В зависимости от того, как вы пишете свой код, у вас также могут возникнуть проблемы с вашей IDE и ее обработкой динамических классов.
...