Java学习之 -----动态编译 - DynamicCompile--反射调用

一、动态编译

1、Java 6.0 引入了动态编译机制。

2、动态编译的应用场景:

可以做一个java的在线编译器,可以在浏览器端编写java代码,服务器动态加载某些类文件进行编译。注意要进行安全检查!!!


二、动态编译的两种方法

1、通过Runtime调用javac,启动新的进程去操作(jdk5.0以前)

Runtime run=Runtime.getRuntime();  
Process process = run.exec("javac -cp e:/java/helloworld.java");  

2、通过javaCompiler动态编译(常用)


JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();  
int flag = compiler.run(null, null, null,"E:/workspace/images/TestJava.java");  
System.out.println(flag == 0 ? "编译成功" : "编译失败");  
第一个参数:为java编译器提供参数
第二个参数:得到java编译器的输出信息
第三个参数:接受编译器的错误信息
第四个参数:可变参数(是一个String数组)能传入一个或多个java源文件
返回值:0表示编译成功,非0表示编译失败

三、动态运行编译好的类

1.通过Runtime.getRuntime()运行启动新的进程运行

例如:
Runtime run = Runtime.getRuntime();  
Process process = run.exec("java -cp E:/workspace/images   TestJava");  


2.通过反射运行编译好的类

例如:

try {  
    URL[] urls = new URL[] { new URL("file:/" + "E:/workspace/images/") };  
    URLClassLoader loader = new URLClassLoader(urls);  
    // 通过反射调用此类  
    Class clazz = loader.loadClass("TestJava");  
    Method m = clazz.getMethod("main", String[].class);  
    // m.invoke(null,new String[]{"aa","bb"});  
    // 由于可变参数是jdk5.0之后才有,上面代码会编译成m.invoke(null,"aa","bb");会发生参数不匹配的问题  
    // 因此必须加上Object 强转  
    m.invoke(null, (Object) new String[] {});  
  
} catch (Exception e) {  
    e.printStackTrace();  
}  
注意:反射中的可变参数


整体Demo:

public class TestCompil {  
    public static void main(String[] args) throws IOException {  
        // 通过IO流创建一个临时文件,然后动态编译  
        String strjava = "public class TestJava{public static void main(String[] args){System.out.println(\"nihao\");}}";  
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(  
                new FileOutputStream("E:/workspace/images/TestJava.java")));  
        bw.write(strjava);  
        bw.flush();  
        bw.close();  
        //动态编译  
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();  
        int flag = compiler.run(null, null, null,"E:/workspace/images/TestJava.java");  
        System.out.println(flag == 0 ? "编译成功" : "编译失败");  
          
        //两种动态执行编译方法  
        //1.通过Runtime.getRuntime();启动新的线程进行  
        Runtime run = Runtime.getRuntime();  
        Process process = run.exec("java -cp E:/workspace/images   TestJava");  
          
        InputStream is = process.getInputStream();  
        BufferedReader bis = new BufferedReader(new InputStreamReader(is));  
        String info = null;  
        while (null != (info = bis.readLine())) {  
            System.out.println(info);  
        }  
          
        //2.通过反射动态执行  
        try {  
            URL[] urls = new URL[] { new URL("file:/" + "E:/workspace/images/") };  
            URLClassLoader loader = new URLClassLoader(urls);  
            // 通过反射调用此类  
            Class clazz = loader.loadClass("TestJava");  
            Method m = clazz.getMethod("main", String[].class);  
            // m.invoke(null,new String[]{"aa","bb"});  
            // 由于可变参数是jdk5.0之后才有,上面代码会编译成m.invoke(null,"aa","bb");会发生参数不匹配的问题  
            // 因此必须加上Object 强转  
            m.invoke(null, (Object) new String[] {});  
  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
    }  
  
}  


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值