JavaCompiler动态编译java代码
运行时将一段String流编译成一个class文件
自定义compiler
核心代码是JavaCompiler.CompilationTask, 通过调用JavaCompiler.CompilationTask.call方法
编译无误返回true,反之返回false
参数:out - 用于来自编译器的其他输出的 Writer;如果为 null,则使用 System.err
fileManager - 文件管理器;如果为 null,则使用编译器的标准文件管理器标准文件管理器有两个用途:
• 自定义编译器如何读写文件的基本构建块
• 在多个编译任务之间共享
diagnosticListener - 诊断侦听器;如果为 null,则使用编译器的默认方法报告诊断信息
options - 编译器选项; null 表示没有选项
classes - 类名称(用于注释处理), null 表示没有类名称
compilationUnits - 要编译的编译单元; null 表示没有编译单元
此处我们自定了fileManager,用于接收String类型输入。编译单元是单个的String流
package io.github.kennethfan.compiler;
import javax.tools.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* Created by kenneth on 2023/5/28.
*/
public class RuntimeCompiler {
private JavaCompiler javaCompiler;
public RuntimeCompiler() {
this.javaCompiler = ToolProvider.getSystemJavaCompiler();
}
public Class<?> compileAndLoad(String fullName, String sourceCode) throws ClassNotFoundException {
DiagnosticCollector<? super JavaFileObject> diagnosticCollector = new DiagnosticCollector<>();
JavaFileManager javaFileManager = new ClassFileManager(this.javaCompiler.getStandardFileManager(diagnosticCollector, null, null));
List<JavaFileObject> javaFileObjectList = new ArrayList<>();
javaFileObjectList.add(new JavaSourceObject(fullName, sourceCode));
JavaCompiler.CompilationTask task = this.javaCompiler.getTask(null, javaFileManager, diagnosticCollector, null, null, javaFileObjectList);
if (task.call()) {
return javaFileManager.getClassLoader(null).loadClass(fullName);
}
System.out.println(diagnosticCollector.getDiagnostics().get(0).getLineNumber());
System.out.println(diagnosticCollector.getDiagnostics().get(0).getColumnNumber());
System.out.println(diagnosticCollector.getDiagnostics().get(0).getMessage(Locale.ENGLISH));
System.out.println(diagnosticCollector.getDiagnostics().get(0).getSource());
System.out.println(diagnosticCollector.getDiagnostics().get(0).getCode());
return Class.forName(fullName);
}
}自定义源文件处理
自定义源文件处理,核心方法是getCharContent,返回源码内容,kind=SOURCE
自定义输出文件处理
接下来自定义编译class文件处理,
自定义JavaFileManager
接下来实现JavaFileManager,此处继承ForwardingJavaFileManager
测试

最后更新于