Самоизменяющийся код в Java

Вы когда-нибудь создавали или встречали самоизменяющийся код в Java? Если да, то, пожалуйста, отправьте ссылку или просто отправьте код.

7 ответов

Решение

Не обращая внимания на мир скорби, который вы можете причинить себе с помощью самоизменяющегося кода (!), Мне кажется, есть 3 варианта:

  1. использовать встроенную поддержку компилятора Java 6 и писать / перекомпилировать / перезагружать классы
  2. используйте библиотеку Apache BCEL для манипулирования байт-кодом, чтобы написать свой класс напрямую
  3. использовать встроенную поддержку сценариев Java 6 (или использовать Apache BSF) для написания методов на выбранном вами языке сценариев JVM и выполнять их

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

Вы можете написать (Java) код, который генерирует новые классы (байт-код) во время выполнения, используя такую ​​библиотеку, как bcel. Это не совсем то же самое, что и самоизменяющийся код. Я подозреваю, что самоизменяющийся код не поддерживается JVM.

Для примера генерации нового кода во время выполнения взгляните на исходный код clojure.

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

От BCEL:

Byte Code Engineering Library предназначена для того, чтобы предоставить пользователям удобную возможность анализировать, создавать и манипулировать (двоичными) файлами классов Java (заканчивающимися на.class). Классы представлены объектами, которые содержат всю символьную информацию данного класса: в частности, методы, поля и инструкции байт-кода.

Я вижу эти варианты для этой цели:

  • Сгенерируйте исходный код java и скомпилируйте его с помощью внешнего javac или встроенных инструментов компилятора (не помню названия). И поскольку вы несете ответственность за присвоение имен, просто включите счетчик версий в имя класса, чтобы избежать аномалий загрузки классов.
  • Используйте встроенную поддержку движка JavaScript
  • Некоторые сценарии могут быть решены с помощью Java Proxys

Редактировать: однажды я создал программу на Java 1.4, которая брала бизнес-правила из существующей устаревшей базы данных, генерировала java-файлы (в основном реализации интерфейса Predicate) с кучей println() из них и использовала командную строку javac для их компиляции.

Будучи студентом, я начал работать над JikesRVM. Это JVM, реализованная (в основном) в Java. Во время выполнения он будет JIT компилировать сам! Это действительно крутая технология.

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

Другие вопросы по тегам