Java之动态编译,静态编译简单理解和实例

2017-01-13 15:07:22来源:csdn作者:huangwenyi1010人点击

开心一笑

【年底是各种案件的高发期,我们去ATM取钱的时候,一定要注意遮挡,不要被陌生人看到你的余额,要不然啊,就,,,非常容易被人嘲笑。其实对于胖子来说,买衣服最简单了,都不用进去。直接就在门口问一句:“老板,有我能穿的衣服么”? 老板瞅了我一眼:“没有”! 那我就毫不犹豫的走到下一家。反正在胖子的眼里,衣服没有好看不好看,只有能穿和不能穿! 】

提出问题

java中的动态编译和静态编译如何理解???

解决问题

唯美图片

1.概念

静态编译:一次性编译。在编译的时候把你所有的模块都编译进去。

动态编译:按需编译。程序在运行的时候,用到那个模块就编译哪个模块。

2.实例

例一:

/**
* @Author 阿毅
* Created by Ay on 2016/01/05.
*/
class Ay{
public static void main(String[] args) {
//如编译后的Boy.class文件消失,会报错误:java.lang.NoClassDefFoundError
Boy boy = new Boy();
boy.sayHello();
}
}class Boy implements Person{
public void sayHello(){
System.out.println("say hello .....");
}
}interface Person{
void sayHello();
}

例二:

比如开发一个阅读器,支持txt,pdf,doc三种格式。我们把读txt,读pdf,读doc定义为三个功能模块。

静态编译:我想看个txt,点击应用程序图标以后,三个功能都加载进来了。在这里,另外两个模块的作用就是占用系统资源。

动态编译:我想看个txt,点击应用程序,判断格式,只加载读txt模块,使用读txt模块。。。 显然,动态编译1速度快,2节省了系统资源,3利于今后拓展。。。。。。。。

例三:

把下面的例子拷贝到上面的main方法中:

/**
* @Author 阿毅
* Created by Ay on 2016/01/05.
*/
public class Ay{
public static void main(String[] args) {
System.out.println("请输入您要输入的类的名字");
//输入一个类的名字
java.util.Scanner sc = new java.util.Scanner(System.in);
String s = sc.next();
//加载这个类
Class c = Class.forName(s);
//获得这个类的实例化对象
Object obj = c.newInstance();
//强制转型
Person person = (Person)obj;
person.sayHello();
}}

我们把编译文件Boy.class删除,上面代码编译并未报错。但是运行时候会出现NoClassDefFoundError异常,这时候我们用把删除掉的Boy.class重新放回原处,重新运行,这时候,代码就可以正常运行。

这样我们可以在不停止程序运行的情况下,动态地加载一个类。我认为这体现出了Java的动态性。通过上面的例子,我认为java语言是一种“半动态”性的语言。

3.最简单的动态编译例子/**
* @Author 阿毅
* Created by Ay on 2016/01/05.
*/
public class Ay{
public static void main(String[] args) throws Exception{
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
int flag = compiler.run(null, null, null,"D://HelloWorld.java");
System.out.println(flag == 0 ? "编译成功" : "编译失败");
}
}
/**
* D盘放置的类的内容
* Created by HuangWenYi on 2017/1/6.
*/
public class HelloWorld {public static void main(String[] args) {
System.out.println("Hello World");
}
}

解释一下: 第一个参数:为java编译器提供参数 第二个参数:得到java编译器的输出信息 第三个参数:接受编译器的错误信息 第四个参数:可变参数(是一个String数组)能传入一个或多个java源文件 返回值:0表示编译成功,非0表示编译失败

4.动态运行编译好的类/**
* @Author 阿毅
* Created by Ay on 2016/01/05.
*/
public class Ay{
public static void main(String[] args) throws Exception{
//获得系统的java编译器
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//编译文件,编译成功返回 0 否则 返回 1
int flag = compiler.run(null, null, null,"D://HelloWorld.java");
System.out.println(flag == 0 ? "编译成功" : "编译失败");
//指定class路径,默认和源代码路径一致,加载class
URLClassLoader classLoader = new URLClassLoader(new URL[]{new URL("file:/d:/")});
Object printer = classLoader.loadClass("HelloWorld").newInstance();
System.out.println(printer.toString());}
}

运行结果

编译成功
HelloWorld@4c583ecf
5.慎用动态编译
在框架中谨慎使用
不要在要求高性能的项目使用 动态编译毕竟需要一个编译过程,与静态编译相比多了一个执行环节,因此在高性能项目中不要使用动态编译。
动态编译要考虑安全问题 它是非常典型的注入漏洞,只要上传一个恶意Java程序就可以让你所有的安全工作毁于一旦。
记录动态编译过程 建议记录源文件、目标文件、编译过程、执行过程等日志,不仅仅是为了诊断,还是为了安全和审计,对Java项目来说,空中编译和运行是很不让人放心的,留下这些依据可以更好地优化程序。
读书感悟

来自电影《长城》


人类和怪物的贪婪是没有区别的。
你以后会证明你的勇敢。
我苦练一生,只为此一战。
经典故事

【哈佛一调查报告说,人生平均只有7次决定人生走向的机会,两次机会间相隔约7年,大概25岁后开始出现,75岁以后就不会有什么机会了。这50年里的7次机会,第一次不易抓到,因为太年轻;最后一次也不用抓,因为太老。这样只剩5次,这里面又有两次会不小心错过,所以实际上只有3次机会了。】

参考文章

【1】Java中的动态和静态编译 【2】动态编译和静态编译及Java执行 【3】动态生成java、动态编译、动态加载 【4】java笔记十一:动态编译 【5】Java学习之-动态编译-DynamicCompile_反射调用 【6】Java动态编译 【7】编写高质量代码:改善Java程序的151个建议

唯美图片

其他

如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎点赞、顶、欢迎留下宝贵的意见、多谢支持!


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台