博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
动态编译
阅读量:7061 次
发布时间:2019-06-28

本文共 2937 字,大约阅读时间需要 9 分钟。

 

       在说动态编译之前先说说静态编译,静态编译就是你在编译程序生成.exe文件时编译器会将所有的模块加载进去,这样一来只要一启动文件,那么所有的模块都会被加载,小的一些程序不存在什么大的问题,但如果程序过大,这样就会让无用模块占用系统资源。而动态编译是先将你所有的模块编写成DDL(dynamic link library),DDL我们后边专门再讲,编写成DLL之后,程序在运行过程中用到哪个模块就加载哪个模块,不会加载无用的模块占用系统资源。

  DDL:指的是动态链接库,存在格式为.ddl,该文件中一般存在着一些可以供不同程序都可以使用的模块,所有动态编译的可执行性文件都带有DDL,如果没有那么这个程序就不能正常运行了。

  这里我再举一个例子,形象的来比喻一下动态编译和静态编译的区别:

  静态编译好比学校要举办一场篮球比赛,你是负责场地的,他们只告诉你去某某篮球场预定一个他们常用的场地,你到达了篮球场但是发现有三个场地,这个时候你也不知道他们常用的哪个,所以你就全部占了下来,然而他们真正使用的时候也是只是用一个场地,这样就导致了资源的浪费,那么动态编译就是说,你们要A场地我就占A场地,要B就占B,这样就不会影响其他场地的正常使用了。

  动态编译

  动态编译的两种做法:

  (1)、通过Runtime调用Javac,启动新的进程去操作

      Runtime run=Runtime.getRuntime();

      Process process=run.exec("javac -cp d:/myjava/ HelloWorld.java");

  (2)、通过JavaCompiler动态编译

  这里我使用第二种编译。

  代码如下:

public static int compileFile(String sourceFile) {        JavaCompiler compiler=ToolProvider.getSystemJavaCompiler();        int result=compiler.run(null,null,null,sourceFile);        System.out.println(result==0?"编译成功":"编译失败");        return result;    }

 

  第一个参数:为Java编译器提供一个参数,是InputStream,如果为null则默认是控制台输入system.in 

  第二个参数:是OutputStream,可以获得编译器的输出信息,如果为null则默认是控制台输出system.out 

  第三个参数:也是一个输出流,接受编译器输出的一些错误信息,如果为null则默认是把错误消息输出在控制台上 system.error 

  第四个参数:可以传递多个Java源文件地址。

  返回值:0表示成功,其他数表示失败

  第一次使用时报错为空指针异常,检查了一遍代码发现并没有错误,百度之后找到了问题所在:

  ToolProvider用到的是jdk里的tool.jar包,而jre里没有这个jar文件,而我使用的就是jre,所以报了空指针异常,将jre换成jdk后问题便得到了解决,通过这个问题我也明白了jdk是开发用的,jre是运行用的,并且jre里的东西没有jdk全,所以用jdk更好

  动态运行

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

  

public class DynamicComplier {    public static void main(String[] args)  {        JavaCompiler compiler=ToolProvider.getSystemJavaCompiler();        int result=compiler.run(null, null, null,"E:/MyJava/Myjava.java");        System.out.println(result==0?"编译成功":"编译失败");                Runtime run=Runtime.getRuntime();                    Process process;            try {                process = run.exec("java -cp E:/MyJava Myjava");                InputStream in=process.getInputStream();                BufferedReader reader=new BufferedReader(new InputStreamReader(in));                String str="";                while((str=reader.readLine())!=null) {                    System.out.println(str);                }            } catch (IOException e) {                // TODO 自动生成的 catch 块                e.printStackTrace();            }                }}

 

  通过反射运行编译好的类

 

try {            URL[] urls=new URL[] {
new URL("file:/"+"e:/myJava/")}; URLClassLoader loader=new URLClassLoader(urls); Class c=loader.loadClass("Myjava"); //调用加载类的main方法 Method m=(Method) c.getMethod("main", String[].class).invoke(null,(Object)new String[] {"aa","bb"}); //可变参数是JDK5.0之后才有的,上述代码会编写成m.invoke(null,"aa","bb"), //这样一来就与Main函数发生了参数不匹配的问题。 }catch (Exception e) { e.printStackTrace(); }

 

 

 

  

 

posted on
2019-04-08 22:21 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/tutuhome/p/10673945.html

你可能感兴趣的文章
原生js如何实现图片翻转旋转效果?
查看>>
黑苹果,Win7,Win10,Xp 各个系统镜像文件下载地址(备用)
查看>>
把mysql的数据导出成txt
查看>>
死锁查看处理(三)
查看>>
资源预加载preload和资源预读取prefetch简明学习
查看>>
EF 延迟加载和预先加载
查看>>
Asp.net 中高亮显示搜索关键字简单方法
查看>>
最近ES遇到discover老是失败问题,ping主节点和node节点正常,抓包发现了大量的retransmission、tcp out of order、dup ack问题。...
查看>>
CentOS下使用crontab+mysqldump实现定时自动备份数据库
查看>>
Kubernetes 在网易云中的落地优化实践
查看>>
算法题待做
查看>>
Python源码中的PyCodeObject
查看>>
ecshop后台新功能及权限的添加
查看>>
spring定时任务.线程池,自定义多线程配置
查看>>
Java程序员的日常—— IOUtils总结
查看>>
SpringBoot(十)应用监控Actuator
查看>>
MongoDB学习笔记(3)--删除数据库
查看>>
JQuery Checkbox 获取多选值 Checkbox选中个数
查看>>
spring boot mvc系列-静态资源配置与MappingHandler拦截器
查看>>
Postgresql查询出换行符和回车符:
查看>>