可程式設計的編譯器

banq發表於2009-12-24
Java透過反射機制可以動態載入一個編譯好的類,那麼能否直接載入原始碼類呢?Java 6的javax.tools包提供了在執行時刻,對Java原始碼編譯等功能。可用於:
1. 在檔案伺服器上生成一個Java檔案,然後編譯它。
2. 編譯Java檔案,然後生成一個Jar檔案,如果這個Jar檔案在classpath中,我們是否可動態載入這個Jar呢?
3. 編寫自己的IDE工具。

詳細使用見文章:Programmatic Compilation with Java

以下是案例程式碼:

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;

import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
import sun.tools.java.ClassFile;

public class CodeCompiler {

	public static void main(String[] args) {
		try{
			JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
			StandardJavaFileManager fileManager = compiler.getStandardFileManager(
					null, null, null);
			Iterable compilationUnits1 = fileManager
					.getJavaFileObjects("D:\\TestClass.java");
			CompilationTask task = compiler.getTask(null, fileManager, null, null,
					null, compilationUnits1);

			// Perform the compilation task.
			task.call();
			fileManager.close();
			ClassFile cf = new ClassFile(new File("TestClass.class"));
			validateDefaultMethods(cf);

		}catch(IOException ioe){
			ioe.printStackTrace();
		}
	}

	   protected static void validateDefaultMethods(ClassFile clazzInfo) {
	        boolean hasEquals = false;
	        boolean hasHashCode = false;
	        boolean hasToString = false;
	        for (Method method : clazzInfo.getClass().getMethods()) {
	            String methodName = method.getName();
	            Class[] types = method.getParameterTypes();
	            if ("equals".equals(methodName) && types.length == 1) {
	                if ("java.lang.Object".equals(types[0])) {
	                    hasEquals = true;
	                }
	            } else if ("hashCode".equals(methodName) &&
	            		types.length == 0) {
	                hasHashCode = true;
	            }else if("toString".equals(methodName)&&
	            		types.length == 0){
	            	hasToString = true;

	            }
	        }
	        if(hasEquals&&hasHashCode&&hasToString){
	        	System.out.println("Valid Code");
	        }else{
	        	System.out.println("Invalid Code");
	        }
	    }

}
<p class="indent">

相關文章