尚学堂 214 动态编译代码

编译完成后产生的是一个class文库

 

生成class文件之后,可以使用反射机制运行class文件URLClassLoader

 

有几个地方需要注意的

第一:helloworld没有包名,如果有包名就要把代码放在对应的包名目录下面

第二:执行main函数的时候需要传人形参

public static void main(String[] args) 

  m.invoke(null, (Object)new String[]{"aa","bb"});第一个参数是执行main函数对应的对象,因为main函数是static,不需要对象,所以第一个参数是null,第二个是传递给main函数的形参具体值,这里是一个字符数组

如果不写成(Object)new String[]{"aa","bb"},而写成new String[]{"aa","bb"}会编译成:m.invoke(null,"aa","bb"),就发生了参数个数不匹配的问题。

我们来看程序的代码

public class HelloWorld {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
      System.out.println("hello wordld");
    }

}
package com.bjsxt.test;


import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;

/**
 * 测试java的动态编译
 * @author 尚学堂高淇 www.sxt.cn
 *
 */
public class Demo01 {
    public static void main(String[] args) throws Exception {
        
        //通过IO流操作,将字符串存储成一个临时文件(Hi.java),然后调用动态编译方法!
        String str = "public class Hi {public static void main(String[] args){System.out.println(\"HaHa,sxt!\");}}";
        
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        int result = compiler.run(null, null, null, "c:/myjava/HelloWorld.java");
        System.out.println(result==0?"编译成功":"编译失败");
        
        //编译成功后会生成c:/myjava/HelloWorld.class文件
        //通过Runtime调用执行类
//        Runtime run = Runtime.getRuntime();  
//        Process process = run.exec("java -cp  c:/myjava    HelloWorld");  
//        
//        InputStream in = process.getInputStream();
//        BufferedReader reader = new BufferedReader(new InputStreamReader(in));
//        String info = "";
//        while((info=reader.readLine())!=null){
//            System.out.println(info);
//        }
        
        
        
        
         try {
             URL[] urls = new URL[] {new URL("file:/"+"C:/myjava/")};
             URLClassLoader loader = new URLClassLoader(urls);
             Class c = loader.loadClass("HelloWorld");
             //调用加载类的main方法
             Method m = c.getMethod("main",String[].class);
             m.invoke(null, (Object)new String[]{"aa","bb"});
             //由于可变参数是JDK5.0之后才有。
             //m.invoke(null, (Object)new String[]{});会编译成:m.invoke(null,"aa","bb"),就发生了参数个数不匹配的问题。
             //因此,必须要加上(Object)转型,避免这个问题。
             //public static void main(String[] args)
             
         } catch (Exception e) {
             e.printStackTrace();
         }


        
    }
}

程序运行的代码的结果是:

编译成功
hello wordld

 

posted on 2017-08-02 18:55  luzhouxiaoshuai  阅读(196)  评论(0编辑  收藏  举报

导航