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

StackOverflow https://stackoverflow.com/questions/781805

Вопрос

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

Возможно, это немного перебор, т. Апач BCEL (Инженерная библиотека байт-кода) может использоваться для создания class файлы во время выполнения.

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

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

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

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top