Определение класса во время работы приложения Java
В Java можно ли создать определение класса "на лету" во время работы приложения, а затем создать объект этого класса?
Например, запущенное приложение будет читать текстовый файл, содержащий список членов класса для включения в новый класс. Затем приложение определяло определение класса, основанное на списке членов, а затем навязывало его.
Ответы
Ответ 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
Был недавно задан вопрос о компиляции в памяти, который должен дать вам некоторые подсказки о том, что делать после того, как вам удалось создать исходный код.