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

开心一笑

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

唯美图片.png

提出问题

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个建议

唯美图片.png

其他

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,505评论 18 399
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,073评论 25 707
  • 今天主要学习了MFC: 1.Windows程序的内部运行原理 Windows程序设计是一种事件驱动的程序设计方法。...
    孙世龙阅读 290评论 0 0
  • 请别责怪我太过投入。我只是一次偶尔间,忘记了踏上归途。天荒地老的传说,终敌不过红尘流转十载暗哑的蹉跎
    剑仙裴宣阅读 211评论 0 1