zoukankan      html  css  js  c++  java
  • 尚学堂 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

  • 相关阅读:
    django路由——关于路由最后斜杠的问题
    django-admin 汉化
    动态绑定属性、方法 以及 __slots__
    type()、获取对象信息
    String,StringBuffer,StringBuilder三种的性能差异
    线程创建的三种方式的比较(继承Thread,Runnable接口,Callable接口)
    单例设计模式
    用Dockerfile来build原理和过程
    etcd和redis
    win10部署docker和mongo
  • 原文地址:https://www.cnblogs.com/kebibuluan/p/7275474.html
Copyright © 2011-2022 走看看