Java 动态编译基础学习

本文详细介绍了Java动态编译的两种方法,包括通过Runtime调用javac和使用JavaCompiler进行动态编译。同时,提供了代码示例,展示了如何通过反射运行编译后的类。


注:JAVA 6.0开始引入了动态编译机制。


动态编译的应用场景:

  • 可以做一个浏览器端编写java代码,上传服务器编译和运行的在线评测系统。
  • 服务器动态加载某些类文件进行编译

动态编译的两种做法:

  • 通过Runtime调用javac ,启动新的进程去操作(1.6之前的做法)
Runtime run = Runtime.getRuntime0;
Process process = run.exec("javac -cp d:/myjava/ HelloWorld.java");
  • 通过JavaCompiler动态编译。

通过JavaCompiler动态编译

public static int compileFile(String sourceFile){
	//动态编译
	JavaCompiler compiler = ToolProvider.getSystemJavaCompiler0;
	int result = compiler.run(null, null, null,sourceFile);
	System.out.printin(result =0?”编译成功”:"编译失脱";
	return result;
}
  • 第一个参数:为java编译器提供参数
  • 第二个参数:得到Java编译器的输出信息
  • 第三个参数:接收编译器的错误信息
  • 第四个参数:可变参数(是一个String数组)能传入一个或多个Java源文件(相当于一个字符串数组)
  • 返回值: 0表示编译成功,非0表示编译失败

动态运行编译好的类

  • 通过Runtime. getRuntime(运行启动新的进程运行
Runtime run = Runtime getRuntime();
Process pfocess = run.exec("java -cp d:/myjava
HelloWorld");
//Process process = run.exec("java -Cp "+dir+" "+ClassFile);
  • 通过反射运行编译好的类
//通过反射运行程序
public static void runJavaClassByReflect(String dir,String classFile) throws
Exception{
	try {
			URL[] ur's = new URL[] {new URL("fle:/"+din)};
			URLClassLoader loader = new URLClassLoader(urs);
			Class C = loader.loadClass(classFile);
			//调用加载类的main方法
			C.getMethod'main",Stringl class) invoke(nul. (Object)new
			String[0):
		} catch (Exception e) {
			e. printStackTrace();
		}
}

代码演示:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

import org.omg.CORBA.portable.InputStream;

public class Demo01 {
	public static void main(String[] args) throws IOException {
		//动态编译字符串中的代码:通过IO流操作,将字符串存储成一个临时文件(Hi.java),然后调用动态编译方法
		String str = "public class HelloWorld {public static void main(String[] args) {System.out.println(\"hello, world\");}}";
		
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		int result = compiler.run(null, null, null, "c:/myjava/HelloWorld.java");
		System.out.println(result==0?"编译成功":"编译失败");
		
		
//		//通过Runtime调用执行类
//		Runtime run = Runtime.getRuntime();
//		Process process = run.exec("java -cp c:/myjava HelloWorld");
//		
//		//为了在控制台中方便观察,进行以下操作
//		java.io.InputStream in = process.getInputStream();
//		BufferedReader reader = new BufferedReader(new InputStreamReader(in));
//		String info = "";
//		while((info=reader.readLine())!=null){
//			System.out.print(info);
//		}
		
		
		
		
		//通过反射运行编译好的类
		try{
			URL[] urls = new URL[] {new URL("file:/"+"C:/myjava/")};
			URLClassLoader loader = new URLClassLoader(urls);
			Class c = loader.loadClass("HelloWorld");
			//调用加载类的卖弄方法
			Method m = c.getMethod("main", String[].class);
			m.invoke(null, (Object)new String[]{"aa","bb"});
			//由于可变参数是jdk5.0之后才有的,上面代码会编译成:m.invoke(null, "aa", "bb"),
			//就发生了参数个数不匹配的问题,因此,必须要加上(Object)转型,避免这个问题
		}catch(Exception e){
			e.printStackTrace();
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逍遥自在”

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值