java动态编译
动态编译,顾名思义,就是在jvm运行过程中可以编译运行其他java代码。
亦是通过《编写高质量代码》此书看到的案例,特此记录。
http://yuedu.163.com/book_reader/d050cae1f7cf4137ac28109827cbe90b_4
主要是:
JavaCompiler cmp = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm = cmp.getStandardFileManager(null, null, null);
JavaCompiler是编译器,用来负责调用任务编译文件;
StandardJavaFileManager 中API解释如下,This file manager creates file objects representing regular files, zip file entries, or entries in similar file system based containers. 为了生成文件而存在的。
JavaFileObject 关于此类查看API解释如下,File abstraction for tools operating on Java™ programming language source and class files.可以看出应该是和需要动态编译的源码以及要生成的class文件有关。
下面是动态编译的一个案例代码
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
public class Client {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
String sourceStr =
"public class Hello{"
+"public String sayHello(String name){"
+ "return \"Hello,\"+name+\"!\";"
+ "}"
+ "}";
String clsName = "Hello";
String methodName = "sayHello";
JavaCompiler cmp = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm = cmp.getStandardFileManager(null, null, null);
JavaFileObject jfo = new StringJavaObject(clsName,sourceStr);
List<String> optionsList = new ArrayList<String>();
optionsList.addAll(Arrays.asList("-d","./target/classes"));
List<JavaFileObject> jfos = Arrays.asList(jfo);
JavaCompiler.CompilationTask task = cmp.getTask(null, fm, null, optionsList, null, jfos);
if(task.call()) {
Object obj = Class.forName(clsName).newInstance();
Class<? extends Object> cls = obj.getClass();
Method m = cls.getMethod(methodName, String.class);
String str = (String) m.invoke(obj, "Dynamic Complilation");
System.out.println(str);
}
}
}
其中./target/classes是存放class文件的目录,即编译目录,这是建立的一个maven工程,如图运行后在classes目录生成Hello.class文件
import java.io.IOException;
import java.net.URI;
import javax.tools.SimpleJavaFileObject;
public class StringJavaObject extends SimpleJavaFileObject{
private String content = "";
public StringJavaObject(String _javaFileName,String _content) {
super(_createStringJavaObjectUri(_javaFileName),Kind.SOURCE);
content = _content;
}
private static URI _createStringJavaObjectUri(String name) {
return URI.create("String:///"+name+Kind.SOURCE.extension);
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException{
return content;
}
}
当编译完成,并且成功后就会调用Hello类中的方法,如下代码所示:
if(task.call()) {
Object obj = Class.forName(clsName).newInstance();
Class<? extends Object> cls = obj.getClass();
Method m = cls.getMethod(methodName, String.class);
String str = (String) m.invoke(obj, "Dynamic Complilation");
System.out.println(str);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?