2009-04-23 2 views
17

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

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

+25

Так начинается SkyNet. – TheTXI

+7

Если SkyNet были написаны на Java, для этого потребовалось бы слишком много памяти, чтобы быть угрозой. – Pesto

+4

SkyNet просто построит себе более крупный кластер для работы. Тот факт, что он написан на Java, будет иметь смысл, так как SkyNet и Java оба станут концом человечества. – TheTXI

ответ

11

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

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

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

1

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

2

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

0

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

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

0

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

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

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

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

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

0

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

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

0

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

+0

Привет, Стефан, поэтому Groovy может помочь скомпилировать во время выполнения Java-класс «на лету» и создать его экземпляр? У вас есть указатель на то, как это сделать? – Sergio

0

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

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

1

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

+0

, который будет работать только в том случае, если установлен jdk, правильно? – Sergio

0

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

Смежные вопросы