Java实现运行时编译并动态调用
来源:互联网 发布:excel数据透视表 编辑:程序博客网 时间:2024/06/01 10:26
Java实现运行时编译并动态调用
至于运行时编译有什么优势这里就不赘述了,直接进入主题:
JDK1.6提供了调用javac的接口。我们可以使用这个接口来实现运行时编译java文件,生成.class文件的目的。该类为javax.tools.JavaCompiler类。接下来使用自定义classloader加载,可实现动态调用。
首先,JavaCompiler使用方法如下:
public static int compile(String name){ //获得系统的JavaComiler实例(ToolProvider在javax.javax.tools包中) JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); //定义一个以char字节的形式输出到控制台的字节流 OutputStream out = new OutputStream() { @Override public void write(int b) throws IOException { System.out.print((char)b); } }; //run方法第一个参数为java文件绝对路径(相对路径没试过) //如果出错了,会将javac的信息输出到第三个参数的输出流 //如果返回值为0,说明编译成功 return compiler.run(null, null, out, name); }
我们可以将编译好的文件使用classloader动态加载,并调用新编译的类。当然实现调用,必须要有一个公共接口。为了方便起见,我们将带编译放在该工程src/test目录下。工程目录如图所示:
其中MyTest工程中的Test文件将会在Complie运行时被Complie编译并加载
Test代码如下:
package test;import commonface.DoSomeThing;public class Test implements DoSomeThing{ @Override public String doSomeThing() { return "hello world"; }}
双方的公共接口DoSomeThing:
package commonface;public interface DoSomeThing { public String doSomeThing();}
最后是编译类Complie:
package complie;import commonface.DoSomeThing;import javax.tools.JavaCompiler;import javax.tools.ToolProvider;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.OutputStream;public class Compile { public static int compile(String name){ //注释见上文 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); OutputStream out = new OutputStream() { @Override public void write(int b) throws IOException { System.out.print((char)b); } }; return compiler.run(null, out, out, name); } public static void run(String classPath) throws Exception{ //自定义一个ClassLoader,我们需要重载findclass ClassLoader loader=new ClassLoader(){ @Override protected Class<?> findClass(String className) throws ClassNotFoundException { Class cLass=null; try { //根据绝对路径找到文件 FileInputStream of=new FileInputStream(new File(className)); //一下几步将文件流变成byte数组 ByteArrayOutputStream out = new ByteArrayOutputStream(1000); byte[] b = new byte[1000]; for (int n;(n = of.read(b)) != -1;) { out.write(b, 0, n); } of.close(); byte[] bt=out.toByteArray(); //加载类信息 cLass= defineClass(bt, 0, bt.length); out.close(); } catch (Exception e) { e.printStackTrace(); throw new ClassNotFoundException(); } return cLass; }}; //加载类 Class mc=loader.loadClass(classPath); //强制转型,并调用,结果输出在控制台 DoSomeThing dt=(DoSomeThing)mc.newInstance(); System.out.println(dt.doSomeThing()); } public static void main(String[] args) throws Exception{ if(compile(System.getProperty("user.dir")+"\\..\\MyTest\\src\\test\\Test.java")==0){ System.out.println("Done"); //javac编译的class文件在java文件同一目录下面 run(System.getProperty("user.dir")+"\\..\\MyTest\\src\\test\\Test.class"); } else { System.out.println("Fail"); } }}
文中的Classloader类这里只是简单的提了一下。以后有机会再详细的说吧。另外,改程序在运行成功、如图所示:
成功的编译了Test文件,并调用了Test文件重载的doSomeThing函数,将结果输出到控制台中了。
0 0
- Java实现运行时编译并动态调用
- Java 运行时动态编译源代码原理和实现
- 动态编译、运行JAVA程序
- 动态编译,运行java程序
- java动态编译运行代码
- Java SE6调用动态编译
- Java SE6调用动态编译
- java动态编译实现
- Java 控制台编译Java文件并调用
- java生成java文件并动态编译
- JAVA1.6实现动态编译加载运行
- 在EmEditor上编译并运行JAVA
- 用cmd编译java类并运行
- Notepad++配置编译并运行java代码
- 在EmEditor上编译并运行JAVA
- Java300StudyNote(3)-Java动态编译(DynamicCompile)、动态运行、反射调用mian方法、JavaCompiler.run()空指针问题
- Java调用Scilab-编译运行Javasci v2
- 动态生成编译运行java类
- SCUT引擎简单使用一
- 困在栅栏里的凯撒
- 124. Binary Tree Maximum Path Sum
- 阿里云服务器的设置ftp无法连接问题
- finalize()方法对垃圾回收的影响
- Java实现运行时编译并动态调用
- ActionBar中建立菜单demo
- 高精度之减法模板
- Java中的ThreadLocal源码解析
- ArrayList、Vector、LinkedList有什么区别?
- 计算机网络复习——概述
- PAT(A) - 1052. Linked List Sorting (25)
- 详谈socket请求Web服务器过程
- Eigen: C++开源矩阵计算工具——Eigen的简单用法