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 fileszip 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);
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值