回到顶部
建议17:慎用动态编译
动态编译一直是java的梦想,从Java6开始支持动态编译了,可以再运行期直接编译.java文件,执行.class,并且获得相关的输入输出,甚至还能监听相关的事件 。不过,我们最期望的还是定一段代码,直接编译,然后运行,也就是空中编译执行(on-the-fly),看如下代码:
1 import java.io.IOException;2 import java.lang.reflect.Method;3 import java.net.URI;4 import java.util.ArrayList;5 import java.util.Arrays;6 import java.util.List;7 8 import javax.tools.JavaCompiler;9 import javax.tools.JavaFileObject;10 import javax.tools.SimpleJavaFileObject;11 import javax.tools.StandardJavaFileManager;12 import javax.tools.ToolProvider;13 14 public class Client17 {15public static void main(String[] args) throws Exception {16// Java源代码17String sourceStr = "public class Hello { public String sayHello (String name) {return \"Hello,\"+name+\"!\";}}";18// 类名及文件名19String clsName = "Hello";20// 方法名21String methodName = "sayHello";22// 当前编译器23JavaCompiler cmp = ToolProvider.getSystemJavaCompiler();24// Java标准文件管理器25StandardJavaFileManager fm = cmp.getStandardFileManager(null, null,26null);27// Java文件对象28JavaFileObject jfo = new StringJavaObject(clsName, sourceStr);29// 编译参数,类似于javac
上面代码较多,可以作为一个动态编译的模板程序 。只要是在本地静态编译能够实现的任务,比如编译参数,输入输出,错误监控等,动态编译都能实现 。
【java开发150个建议】Java的动态编译对源提供了多个渠道 。比如,可以是字符串,文本文件,字节码文件,还有存放在数据库中的明文代码或者字节码 。汇总一句话,只要符合Java规范的就可以在运行期动态加载,其实现方式就是实现接口,重写、、,或者实现JDK已经提供的两个、ject,具体代码可以参考上个例子 。
动态编译虽然是很好的工具,让我们可以更加自如的控制编译过程,但是在我们目前所接触的项目中还是使用较少 。原因很简单,静态编译已经能够帮我们处理大部分的工作,甚至是全部的工作,即使真的需要动态编译,也有很好的替代方案,比如Jruby、等无缝的脚本语言 。另外,我们在使用动态编译时,需要注意以下几点:
在框架中谨慎使用:比如要在中使用动态编译,动态实现一个类,它若继承自就希望它成为一个 。能做到,但是debug很困难;再比如在中,写一个动态类,要让它注入到容器中,这是需要花费老大功夫的 。不要在要求性能高的项目中使用:如果你在web界面上提供了一个功能,允许上传一个java文件然后运行,那就等于说:"我的机器没有密码,大家都可以看看",这是非常典型的注入漏洞,只要上传一个恶意Java程序就可以让你所有的安全工作毁于一旦 。记录动态编译过程:建议记录源文件,目标文件,编译过程,执行过程等日志,不仅仅是为了诊断,还是为了安全和审计,对Java项目来说,空中编译和运行时很不让人放心的,留下这些依据可以很好地优化程序 。
- 开发者必看!探秘阿里云Hi购季开发者分会场:海量学习资源0元起!...
- 开发者干货合集!阿里开源,移动开发,机器学习等海量资源限时开放!...
- 个人开发app可以上架吗
- 中天城投河东开发公司,中天城投集团遵义有限公司介绍?
- 精鼎医药研究开发有限公司,中国CRO公司都由哪些
- 中啡咖啡怎么样,java中咖啡标志怎么设置大小
- 如何开发合成物品功能?
- web前端技术:学习HTML、CSS、JavaScript
- 个人起诉开发商很难,多人联名起诉开发商,法院怎么收费
- CycleGAN生成车牌记录