JAVA 的动态编译

来源:互联网 发布:调色软件app 编辑:程序博客网 时间:2024/05/18 12:38

JAVA 6.0引入了动态编译机制,也就是说,你利用java的io流把完整的程序代码写入.java后缀的文件,可以实现载入动态的实现载入,动态代理就是利用了此机制完成的。

javax.tools Interface JavaCompiler


下面假设在D盘根目录下有一个hello.java文件(实际上此文件多数时候应该由java创建):

编译步骤:

1、调用 ToolProvider的getSystemJavaCompiler()方法,返回JavaCompiler 

2、使用JavaCompiler的getStandardFileManager(DiagnosticListener<? superJavaFileObject> diagnosticListener, Locale locale, Charset charset)方法,获取一个StandardJavaFileManager 

3.把获取的StandardJavaFileManager传入 getTask(Writer out, JavaFileManager fileManager, DiagnosticListener<? super JavaFileObject> diagnosticListener, Iterable<String> options,Iterable<String> classes,Iterable<? extendsJavaFileObject> compilationUnits) 方法获得 JavaCompiler.CompilationTask 

4、激活task 即可 task.call();这样文件编译成功了,稍显麻烦。

package test.javaComplile;import java.io.IOException;import java.net.URL;import java.net.URLClassLoader;import javax.tools.JavaCompiler;import javax.tools.JavaCompiler.CompilationTask;import javax.tools.StandardJavaFileManager;import javax.tools.ToolProvider;public class Test {/** * @param args * @throws IOException  * @throws IllegalAccessException  * @throws InstantiationException  * @throws ClassNotFoundException  */public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException {// TODO Auto-generated method stubJavaCompiler complier = ToolProvider.getSystemJavaCompiler();StandardJavaFileManager sjf = complier.getStandardFileManager(null, null, null);Iterable it = sjf.getJavaFileObjects("D:\\hello.java");  CompilationTask task = complier.getTask(null, sjf, null, null, null, it);task.call();  //调用创建sjf.close();URL urls[] = new URL[]{ new URL("file:/D:/")};  //储存文件目录的地址URLClassLoader uLoad = new URLClassLoader(urls);  //classloader从哪个目录找?Class c = uLoad.loadClass("hello");  //找哪个class文件 注意不带后缀名c.newInstance();  //创建一个实例}}

output:

Hello world!


API解释:


Interface JavaCompiler

JavaCompiler.CompilationTask getTask(Writer out, JavaFileManager fileManager, DiagnosticListener<? super JavaFileObject> diagnosticListener, Iterable<String> options, Iterable<String> classes, Iterable<? extends JavaFileObject> compilationUnits) Creates a future for a compilation task with the given components and arguments. The compilation might not have completed as described in the CompilationTask interface. 
使用给定的参数或者组件创建一个(未来使用)的CompilationTask 。如CompilationTask 接口所述,编译有可能没有完成。If a file manager is provided, it must be able to handle all locations defined in StandardLocation. 如果提供了file manager ,他一定能处理所有地方。Note that annotation processing can process both the compilation units of source code to be compiled, passed with the compilationUnits parameter, as well as class files, whose names are passed with the classes parameter. Parameters:

out - a Writer for additional output from the compiler; use System.err if null定义Writer类型输出流 ,null使用System.err输出流

fileManager - a file manager; if null use the compiler's standard filemanager定义fileManager,null使用编译器标准

fileManagerdiagnosticListener - a diagnostic listener; if null use the compiler's default method for reporting diagnostics定义diagnosticListener(诊断监听器)

options - compiler options, null means no options

classes - names of classes to be processed by annotation processing, null means no class names注解类

compilationUnits - the compilation units to compile, null means no compilation units 

Returns:

          an object representing the compilation

Throws: 

          RuntimeException - if an unrecoverable error occurred in a user supplied component. The cause will be the error in user code. IllegalArgumentException - if any of the given compilation units are of other kind than source





getStandardFileManager


为StandardJavaFileManager 创建一个实例
 

The standard file manager will be automatically reopened if it is accessed after calls toflush orclose. The standard file manager must be usable with other tools.

Parameters:

      diagnosticListener - a diagnostic listener for non-fatal diagnostics; ifnull use the compiler's default method for reporting diagnostic

locale - the locale to apply when formatting diagnostics; null means the default locale.
charset - the character set used for decoding bytes; if null use the platform default
Returns:
the standard file manager

原创粉丝点击