Определение класса во время работы приложения Java
-
13-09-2019 - |
Вопрос
Можно ли в 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).
Недавно здесь был вопрос относительно компиляция в памяти который должен дать вам несколько подсказок о том, что делать после того, как вам удалось сгенерировать исходный код.