Java 内存级动态编译

先定义接口:

package Test;
public interface Printer {
	public void print();
}

然后如下:

package Test;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.util.Arrays;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.JavaFileObject.Kind;
import javax.tools.ToolProvider;

public class MyTest {
	//自定义JavaSourceFromString,作为源代码的抽象文件
	static class JavaSourceFromString extends SimpleJavaFileObject{
		final String code ;
		public JavaSourceFromString(String name,String code) {
			super(URI.create("string:///"+name.replace('.', '/')+Kind.SOURCE.extension), Kind.SOURCE);
			this.code = code;
		}
		@Override
		public CharSequence getCharContent(boolean ignoreEncodingErrors){
			return code ;
		}
		
	}
	//JavaClassFileObject,代表class的文件抽象
	static class JavaClassFileObject extends SimpleJavaFileObject{
		ByteArrayOutputStream outputStream=null;
		public JavaClassFileObject(String className, Kind kind) {
			super(URI.create("string:///"+className.replace('.', '/')+kind.extension), kind);
			outputStream = new ByteArrayOutputStream();
		}
		@Override
		public OutputStream openOutputStream() throws IOException{
			return this.outputStream;
		}
		public byte[] getClassBytes(){
			return outputStream.toByteArray();
		}
	}
	//ClassFileManager,修改JavaFileManager生成class的JavaFileObject的行为,另外返回一个自定义ClassLoader用于返回内存中的字节码对应的类模板
	static class ClassFileManager extends ForwardingJavaFileManager<JavaFileManager>{
		private JavaClassFileObject classFileObject;
		protected ClassFileManager(JavaFileManager fileManager) {
			super(fileManager);
		}
		@Override
		public JavaFileObject getJavaFileForOutput(Location location,String className,Kind kind,FileObject sibling) throws IOException{
			classFileObject = new JavaClassFileObject(className, kind);
			return classFileObject;
		}
		@Override
		public ClassLoader getClassLoader(Location location){
			return new ClassLoader() {
				@Override
				protected Class<?> findClass(String name) throws ClassNotFoundException{
					byte[] classBytes = classFileObject.getClassBytes();
					return super.defineClass(name, classBytes, 0, classBytes.length);
				}
			};
		}
	}
	public static void main(String[] args) {
		String string = "package Test; \n" + "public class MyPrint implements Printer{ \n" + "@Override \n"
				+ "public void print() { \n" + "System.out.println(\"MyPrint...\"); \n" + "} \n" + "}";
		//生成源代码的JavaFileObject
		SimpleJavaFileObject fileObject = new JavaSourceFromString("Test.MyPrint", string);
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		//被修改后的JavaFileManager
		JavaFileManager fileManager = new ClassFileManager(compiler.getStandardFileManager(null, null, null));
		//执行编译
		CompilationTask task = compiler.getTask(null, fileManager, null, null, null, Arrays.asList(fileObject));
		task.call();
		//获得ClassLoader,加载class文件
		ClassLoader classLoader = fileManager.getClassLoader(null);
		try {
			Class<?> printClass = classLoader.loadClass("Test.MyPrint");
			//获得实例
			Printer printer = (Printer)printClass.newInstance();
			printer.print();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值