Подтвердить что ты не робот

Определение класса во время работы приложения Java

В Java можно ли создать определение класса "на лету" во время работы приложения, а затем создать объект этого класса?

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

4b9b3361

Ответ 1

Да, это возможно сделать теоретически, ваш файл класса - это байтовый код, который в конце представляет собой массив байтов! вы можете использовать метод defineClass (String, byte [], int, int), чтобы получить экземпляр класса, который может использоваться для создания объектов через отражение.

На практике вы можете использовать что-то вроде CGLib или javaassist.

Вы также можете использовать длинный путь генерации java-кода в файле, вызывая компилятор, а затем загружая файл.

Ответ 2

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

Ответ 3

Вы можете сделать это, написав код для своего нового класса в файл, затем запустив компилятор Java в этом файле и используя загрузчик классов, чтобы динамически загружать этот класс в ваше запущенное приложение. Apache Tomcat делает это для своих страниц JSP; он принимает код, вносит в него некоторые изменения, обертывает его в блок try/catch в середине класса, который затем записывает в файловую систему, компилирует его и использует загрузчик классов для получения и подачи иска на запросы.

Ответ 4

Конечно, это возможно. См., Например, статью .

Ответ 5

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

Ответ 6

Возможно, небольшая перегрузка, Apache BCEL (Библиотека байтового кода) может использоваться для создания файлов class во время выполнения.

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

Ответ 7

Да, это возможно.

Вы можете создавать классы с Javassist во время выполнения, определяя тело класса и делая javassist компилировать ваш новый класс.

Javassist имеет собственный компилятор, который создает байт-код на основе определения вашего класса. У этого есть некоторые особые способы обработки вещей, но это очень легко и интуитивно понятно использовать эту библиотеку.

Javassist используется на JBoss, и я думаю, что это хорошая ссылка:)

То же самое можно достичь с помощью BCEL, однако это намного сложнее (но таким образом у вас больше контроля над тем, что происходит генерируется).

Ответ 8

Возможно, вы могли бы сделать что-то подобное с JRuby или JPython или Groovy, если это необходимо.

Если вы чувствуете себя особенно мазохистом, вы можете посмотреть BCEL.

Ответ 9

Если вы хотите Java и метапрограммирование, используйте Groovy.

Ответ 10

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

После этого вы можете использовать одну из библиотек более высокого уровня, если это упрощает вашу жизнь и понимает, что они делают. Для многих случаев, таких как создание прокси, CGLIB полезен и прост в использовании. Для большей мощности многие упомянули Javassist (я не использовал его - CGLIB и ASM были полезны для меня).

Ответ 11

Был недавно задан вопрос о компиляции в памяти, который должен дать вам некоторые подсказки о том, что делать после того, как вам удалось создать исходный код.