JAVA之动态编译
通过Java动态生成class文件
今天说下JAVA中的动态编译,这个功能根据我现在的了解好像没有见到过用的,我Jio的吧,现在的一些在线代码编缉器可以用到了,这个具体我也不是很清楚。感兴趣的大家可以自已了解下。
说到动态编缉大家可能会想到,动态编缉肯定不是像我们平时运行程序似的在本地的平台就开始编译了。
动态编译其实是在程序的运行过程中对Java文件的编译或者是运行.class的文件。比如说我今天想装一波,我写个java的程序,又写了个另一个java的程序在小伙伴面秀,我只运行一个java程序可以编译另一个java并且运行它。
我们先来了解下,在JAVA的6.0版本java开始引入的动态编译这个功能。其实在java6.0以前java也可以使用动态编译,那个时候好像是用的RunTime来实现的,感兴趣的可以了解下
我们先来说下6.0以后是如何进行动坊编译的呢?
这个时候JAVA引入了JavaCompiler,这个类主要是在程序中调用JAVA编程语言的接口,这个类是没有构造函数的,是接收的ToolsProvider类下的静态函数 getSystemJavaCompiler(),这个函数的主要功能获得此平台提供的Java编程语言编译器。
下面我们看下代码是如何编写的:
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if(compiler == null){
System.out.println("没有得到初始化");
return;
}
int restuld = compiler.run(null,null,null,"D:/myjava/HelloWorld.java");
System.out.println(restuld == 0 ? "编译成功":"编译失败");
这里我来说下这里是什么意思,第一行代码是获得JAVA的编程语言的编译器,第二行是一个判空处理,这里行记得加上,小编在这里遇到了问题卡了10多分钟,我也不知道怎么回事系统没有获取到java语言的编译器,一直 报出空指针异常的问题,我寻找了好久最后加了个判空处理发现这里是空的,后来我也没有处理多运行了几次就好了,如果有朋友发现这里是怎么回事评论下的,第6行代码大家可以理解为是在进行编译java源码程序。这里有4个参数分别是:
- 为java编译器提供参数
- 得到java编译的输出信息
- 接收编译的错误
- 可变参数能传入一个或多个java源码

这里的返回值是如果编译成功返回的是0,编译失败返回非0.
大家可以看下面这张API的截图,可以了解下,

经过程序的运行,我成功的得到了一个HelloWorld.class文件,到这里大家先练习下上面的代码,下面部分是关于如何通过反射来执行编译生成的类。

通过反射来运行生成的Class类
讲到这里我们先来了解下URLClassLoader,这个是类加载器,在我们是用类加载器的时候构造参数是可以传入一个url数组,
我们需要讲类文件的url放到一个Url数组中,可以通过创建url数组包裹url的方式来创建一个url数组,例:
URL[] urls = new URL[]{new URL("file:/" + "D:/myjava/")};
这里new Url的时候不了解的小伙伴可以看下JAVA的API文档url有一个构造参数是传入的一个路径,这个路径是要带上协议的,比如我要加载文件我就要带上file协议,如果找不到协议可能会发生格式错误的异常。

这里的url参数是可以填写目录的,接下来我们要构造一个类加载器(URLClassLoader)可以通过这个类加载器加载我们上面生成的类。
URLClassLoader loader = new URLClassLoader(urls);
使用默认委托父级ClassLoader为指定的URL构造一个新的ClassLoader 。 在首次搜索父类加载器后,将按照为类和资源指定的顺序搜索URL。 任何以“/”结尾的URL都假定是指一个目录。 否则,URL被认为是指根据需要下载并打开的JAR文件。 接下来我们要开始加载生成的类文件了:
Class c = loader.loadClass("HelloWorld");
看到这里相比大家应该很熟悉了吧,这里和我上次给大家说的反射类似,这里拿到了一个class的对象,我们可以通过class的对象查找方法,
Method method = c.getMethod("main",String[].class);
我这里就和大家大概的说下因为我在反射的那篇博客和大家说了,这里就不详细的讲解了,这里填的两个参数的意思是,参数一:是我们要查找的方法名,参数二:是方法的参数类型,在main方法的参数列表里都会有一个String数组类型的参数,主要是接受在命令行工具下填写的参数的。通过这行命令我们拿到了一个方法。接下来开始通过invoke方法你可以理解成调用这个方法:
method.invoke(null,(Object)new String[]{});
这里我们在反射那讲说要填写一个对象,这里我们填写空就可以了,因为在java的main方法是静态的,所以可以直接调用,
这样就可以运行一个类啦,

不上反射的教程,传送门
JAVA之动态编译的更多相关文章
- 深入理解Java的动态编译
前提 笔者很久之前就有个想法:参考现有的主流ORM框架的设计,造一个ORM轮子,在基本不改变使用体验的前提下把框架依赖的大量的反射设计去掉,这些反射API构筑的组件使用动态编译加载的实例去替代,从而可 ...
- Java的动态编译、动态加载、字节码操作
想起来之前做的一个项目:那时候是把需要的源代码通过文件流输出到一个.java文件里,然后调用sun的Comipler接口动态编译成.class文件,然后再用专门写的一个class loader加载这个 ...
- Java程序动态编译Java源文件
最近接触到公司一个项目,需要将生成的源码动态编译,记录下学习过程. 先贴出官网推荐写法: JavaCompiler.CompilationTask getTask(Writer out, ...
- 动态生成java、动态编译、动态加载
我曾经见过一个“规则引擎”,是在应用系统web界面直接编写java代码,然后保存后,规则即生效,我一直很是奇怪,这是如何实现的呢?实际这就好像jsp,被中间件动态的编译成java文件,有被动态的编译成 ...
- JAVA中动态编译的简单使用
一.引用库 pom文件中申明如下: <dependencies> <!-- https://mvnrepository.com/artifact/junit/junit --> ...
- java动态编译笔记
1 前言 Java的动态编译知识,真真在实际开发中并不是经常遇到.但是学习java动态编译有助于我们从更深一层次去了解java.对掌握jdk的动态代理模式,这样我们在学习其他一些开源框架的时候就能够知 ...
- [改善Java代码]慎用动态编译
建议17: 慎用动态编译 //=========这篇博文暂时理解不透......... 动态编译一直是Java的梦想,从Java 6版本它开始支持动态编译了,可以在运行期直接编译.java文件,执行. ...
- (转载)JAVA动态编译--字节代码的操纵
在一般的Java应用开发过程中,开发人员使用Java的方式比较简单.打开惯用的IDE,编写Java源代码,再利用IDE提供的功能直接运行Java 程序就可以了.这种开发模式背后的过程是:开发人员编写的 ...
- Java动态编译
程序产生过程 下图展示了从源代码到可运行程序的过程,正常情况下先编译(明文源码到字节码),后执行(JVM加载字节码,获得类模板,实例化,方法使用).本文来探索下当程序已经开始执行,但在.class甚至 ...
随机推荐
- iOS app submission : missing 64-bit support
- P3231 [HNOI2013]消毒
P3231 [HNOI2013]消毒 二维覆盖我们已经很熟悉了 扩展到三维,枚举其中较小的一维,这里定义为$a$ 以$a$为关键字状压,$1$表示该面全选 剩下的面和二维覆盖一样二分图匹配 如果还没接 ...
- windows server 2008 r2 下发布网站excel有时候无法下载文档
最近将公司网站服务器更新了系统,从win2003 到 win2008 r2 (64bit),一切正常,但是使用网站的过程中发现了一个比较奇怪的问题,就是,有时候网站的excel文档无法下载,但是我什么 ...
- 用户态文件系统fuse学习【转】
本文转载自:https://blog.csdn.net/ty_laurel/article/details/51685193 FUSE概述 FUSE(用户态文件系统)是一个实现在用户空间的文件系统框架 ...
- 0CTF 2017 部分Web的某些不一样的思路
洒家参加了0CTF 2017,做了一些题目.赛后过了好几天,看网上已经有了一些写得不错的Writeup,这里就写一写洒家的一些不一样的思路. 一些不错的Writeup https://ctftime. ...
- shell之起步
初学者,先不要考虑好不好看,效率高不高!先要实现需求!需求是第一位! grep.sed.awk.三剑客! 学好shell,需要前提! 1.linux系统命令熟练 2.搞清楚正则,grep.sed.aw ...
- Python 使用正则表达式验证密码必须包含大小写字母和数字
校验密码是否合法的程序. 输入一个密码 1.长度5-10位 2.密码里面必须包含,大写字母.小写字母和数字 3.最多输入5次 ===================================== ...
- druid相关的时间序列数据库——也用到了倒排相关的优化技术
Cattell [6] maintains a great summary about existing Scalable SQL and NoSQL data stores. Hu [18] con ...
- matplotlib中文显示-微软雅黑
网上有很多方法,但是基本的是片面的. 参考1 https://tracholar.github.io/wiki/python/matplotlib-chinese-font.html 参考2 http ...
- str_1.判断两个字符串每个字符出现的次数一样
1.两个字符串每个字符出现的次数一样 $str1 = "ab'c4*"; $str2 = "cb*'a4"; $ret = isBX($str1, $str2) ...