尚学堂 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   luzhouxiaoshuai  阅读(198)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

点击右上角即可分享
微信分享提示