一般情况下对java源文件的编译均是在代码完成后使用javac编译的,不管是使用 IDE还是直接使用命令行。这里要说的情况是比较特别的,就是在代码内动态的编译一些代码。比如你想通过在某个目录下通过放置一些源代码的方式来实现对程序功能的动态扩展,那么你的程序就需要具有一种对源代码的编译、加载、运行的能力,可能就需要本文介绍的3种方法。

方法1:通过调用本机的javac命令来编译。

在java程序中调用javac命令可以通过调用Runtime类的exec或是ProcessBuilder类的start方法来完成,这两个类的功能基本相同,用法也比较相似,这里的例子我们就用ProcessBuilder来演示。如果是JDK1.5之前的版本请使用Runtime类完成相同的功能。

开始之前先来点准备工作,将下面的类放到 c:\mytest\src\ 目录下,这个类我们不会在IDE中编译,而是由我们程序完成其编译。保存时使用UTF-8格式。可以直接在附件中下载这个类。

Java代码 [img]http://www.doczj.com/doc/69637c3d376baf1ffc4fadb0.html/attachments/images/302-icon_copy.gif[/img]

public class HelloWorld {
public void sayHello(String in)
{
System.out.println("动态编译成功");
System.out.println("使用编译方式:" + in);
}
}
public class HelloWorld {
public void sayHello(String in)
{
System.out.println("动态编译成功");
System.out.println("使用编译方式:" + in);
}
}

准备工作完成,下面就看一下我们程序的代码,这里只列出主要代码

Java代码 [img]http://www.doczj.com/doc/69637c3d376baf1ffc4fadb0.html/attachments/images/302-icon_copy.gif[/img]

public class JavacCompile {
private static String filePath = "c:\\mytest\\src\\HelloWorld.java";
private static String binDir = "c:\\mytest\\bin";
public static void main(String[] args) {
File binOutDir = new File(binDir);
if (!binOutDir.exists())
{
binOutDir.mkdirs();
}
// 设置javac的编译参数,使用-encoding指定编码方式,-d并指定编译生成class文件目录
ProcessBuilder pb = new ProcessBuilder("javac","-encoding", "UTF-8","-d", binDir, filePath);
try {
// 开始调用javac命令编译
final Process proc = pb.start();
// 处理进程的输出,避免挂死
new Thread(new Runnable() {
public void run() {
processStream(proc.getInputStream());
processStream(proc.getErrorStream());
}
}).start();
// 等待编译完成
proc.waitFor();
// 加载编译好的类,并调用相应的方法
new LoaderClassByDir(binDir).execSayHello("javac