How do I programmatically compile and instantiate a Java class?
Как мне программно скомпилировать и создать экземпляр класса Java?
У меня есть имя класса, сохраненное в файле свойств. Я знаю, что хранилище классов реализует IDynamicLoad . Как мне создать экземпляр класса динамически?
Загружает ли newInstance только скомпилированные файлы .class? Как мне загрузить класс Java, который не скомпилирован?
Переведено автоматически
Ответ 1
Как мне загрузить класс Java, который не скомпилирован?
Сначала вам нужно его скомпилировать. Это можно сделать программно с помощью javax.tools API. Для этого требуется только, чтобы JDK был установлен на локальном компьютере поверх JRE.
Вот базовый пример запуска (оставляя в стороне очевидную обработку исключений):
// Prepare source somehow. Stringsource="package test; public class Test { static { System.out.println(\"hello\"); } public Test() { System.out.println(\"world\"); } }";
// Save source in .java file. Fileroot= Files.createTempDirectory("java").toFile(); FilesourceFile=newFile(root, "test/Test.java"); sourceFile.getParentFile().mkdirs(); Files.write(sourceFile.toPath(), source.getBytes(StandardCharsets.UTF_8));
Позволить java.io.File полагаться на текущий рабочий каталог - это путь к проблемам с переносимостью. Не делайте этого. Поместите этот файл в classpath и используйте ClassLoader#getResourceAsStream() с относительным путем classpath.
Он принимает список строк, содержащих исходный код Java, извлекает имена пакета и общедоступного класса / интерфейса и создает соответствующую иерархию каталогов / файлов в каталоге tmp. Затем он запускает над ним компилятор java и возвращает список пар name, classfile (структура ClassInfo).
Разберитесь с кодом самостоятельно. Он лицензирован MIT.
Ответ 3
Ваш прокомментированный код верен, если вы знаете, что у класса есть открытый конструктор без аргументов. Вам просто нужно привести результат, поскольку компилятор не может знать, что класс фактически реализует IDynamicLoad. Итак: