Member 13164805 Ответов: 0

Существует ли более правильный и чистый способ/фреймворк для создания классов (а не их модификации) во время выполнения в 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 было бы проще.

0 Ответов