Существует ли более правильный и чистый способ/фреймворк для создания классов (а не их модификации) во время выполнения в JAVA?
В моем приложении пользователь может указать поля, которые он хочет для класса. Затем эти параметры объединяются с помощью StringBuilder, и в конце у меня есть что-то вроде этого.
String classname = "MyTestClassTest"; StringBuilder sourceCode = new StringBuilder(); //First Create Class MyTestClassTest. String classname = "MyTestClassTest"; sourceCode.append("public class "); sourceCode.append(classname); sourceCode.append(" implements java.io.Serializable {"); sourceCode.append("public String testName"); sourceCode.append(";"); sourceCode.append("public int testNumber"); sourceCode.append(";"); sourceCode.append("public String toString() { return "); sourceCode.append("\"NAME: \""); sourceCode.append("+"); sourceCode.append("testName"); sourceCode.append(";"); sourceCode.append("}"); sourceCode.append("}"); CreateRuntimeClass codeExecuted = new CreateRuntimeClass(classname ,codeToExecute.toString() ); codeExecuted.createFileAndUpdateClassPath();
Затем я использую JavaCompiler для выполнения этого кода, и создается новый класс.
Есть ли лучший способ создавать новые классы во время выполнения?
И есть ли в моем пути какие-то проблемы?
Или есть какие-нибудь предложения, как я могу улучшить свою логику?
И действительно ли байт-код, сгенерированный при компиляции кода, добавляется к пути к классу или как он работает?
Что я уже пробовал:
Я использую следующий код для создания классов во время выполнения.
public class CreateRuntimeClass { private String className; private String sourceCode; private String fileLocation = "C://Users//UserName//workspace//JavaDataStructures//bin//"; public CreateRuntimeClass (String className, String sourceCode) throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { this.className = className; this.sourceCode = sourceCode; //createFileAndUpdateClassPath(); } public void createFileAndUpdateClassPath() throws IOException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException{ String fileName = this.fileLocation + className + ".java"; File myFile = new File(fileName); // write the source code into the source file FileWriter writer = new FileWriter(myFile); writer.write("package datastructure; "+ sourceCode); writer.close(); // compile the source file JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); File parentDirectory = myFile.getParentFile(); fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(parentDirectory)); Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(Arrays.asList(myFile)); compiler.getTask(null, fileManager, null, null, null, compilationUnits).call(); fileManager.close(); System.out.println(parentDirectory.toURI().toURL()); // load the compiled class URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { parentDirectory.toURI().toURL() }); Class<?> helloClass = classLoader.loadClass("datastructure."+this.className); // call a method on the loaded class //Method helloMethod = helloClass.getDeclaredMethod("hello"); //helloMethod.invoke(helloClass.newInstance()); } }
Richard MacCutchan
Это действительно зависит от того, какую проблему вы пытаетесь решить. Возможно, дать пользователям копию JDK было бы проще.