開心一笑
【年底是各種案件的高發(fā)期猫牡,我們?nèi)TM取錢的時候,一定要注意遮擋邓线,不要被陌生人看到你的余額淌友,要不然啊,就骇陈,震庭,,非常容易被人嘲笑你雌。其實對于胖子來說器联,買衣服最簡單了,都不用進去。直接就在門口問一句:“老板主籍,有我能穿的衣服么”? 老板瞅了我一眼:“沒有”! 那我就毫不猶豫的走到下一家逛球。反正在胖子的眼里千元,衣服沒有好看不好看,只有能穿和不能穿颤绕! 】
提出問題
java中的動態(tài)編譯和靜態(tài)編譯如何理解???
解決問題
1.概念
靜態(tài)編譯:一次性編譯幸海。在編譯的時候把你所有的模塊都編譯進去。
動態(tài)編譯:按需編譯奥务。程序在運行的時候物独,用到那個模塊就編譯哪個模塊。
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();
}
例二:
比如開發(fā)一個閱讀器挡篓,支持txt,pdf帚称,doc三種格式官研。我們把讀txt,讀pdf闯睹,讀doc定義為三個功能模塊戏羽。
靜態(tài)編譯:我想看個txt,點擊應用程序圖標以后楼吃,三個功能都加載進來了始花。在這里,另外兩個模塊的作用就是占用系統(tǒng)資源孩锡。
動態(tài)編譯:我想看個txt酷宵,點擊應用程序,判斷格式浮创,只加載讀txt模塊忧吟,使用讀txt模塊。斩披。溜族。
顯然,動態(tài)編譯1速度快垦沉,2節(jié)省了系統(tǒng)資源煌抒,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();
//強制轉(zhuǎn)型
Person person = (Person)obj;
person.sayHello();
}
}
我們把編譯文件Boy.class刪除棒仍,上面代碼編譯并未報錯悲靴。但是運行時候會出現(xiàn)NoClassDefFoundError異常,這時候我們用把刪除掉的Boy.class重新放回原處莫其,重新運行癞尚,這時候,代碼就可以正常運行乱陡。
這樣我們可以在不停止程序運行的情況下浇揩,動態(tài)地加載一個類。我認為這體現(xiàn)出了Java的動態(tài)性憨颠。通過上面的例子胳徽,我認為java語言是一種“半動態(tài)”性的語言。
3.最簡單的動態(tài)編譯例子
/**
* @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盤放置的類的內(nèi)容
* Created by HuangWenYi on 2017/1/6.
*/
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World");
}
}
解釋一下:
第一個參數(shù):為java編譯器提供參數(shù)
第二個參數(shù):得到java編譯器的輸出信息
第三個參數(shù):接受編譯器的錯誤信息
第四個參數(shù):可變參數(shù)(是一個String數(shù)組)能傳入一個或多個java源文件
返回值:0表示編譯成功爽彤,非0表示編譯失敗
4.動態(tài)運行編譯好的類
/**
* @Author 阿毅
* Created by Ay on 2016/01/05.
*/
public class Ay{
public static void main(String[] args) throws Exception{
//獲得系統(tǒng)的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.慎用動態(tài)編譯
- 在框架中謹慎使用
- 不要在要求高性能的項目使用
動態(tài)編譯畢竟需要一個編譯過程爪瓜,與靜態(tài)編譯相比多了一個執(zhí)行環(huán)節(jié),因此在高性能項目中不要使用動態(tài)編譯匙瘪。 - 動態(tài)編譯要考慮安全問題
它是非常典型的注入漏洞铆铆,只要上傳一個惡意Java程序就可以讓你所有的安全工作毀于一旦。 - 記錄動態(tài)編譯過程
建議記錄源文件丹喻、目標文件薄货、編譯過程、執(zhí)行過程等日志碍论,不僅僅是為了診斷谅猾,還是為了安全和審計,對Java項目來說鳍悠,空中編譯和運行是很不讓人放心的税娜,留下這些依據(jù)可以更好地優(yōu)化程序。
讀書感悟
來自電影《長城》
- 人類和怪物的貪婪是沒有區(qū)別的藏研。
- 你以后會證明你的勇敢敬矩。
- 我苦練一生,只為此一戰(zhàn)蠢挡。
經(jīng)典故事
【哈佛一調(diào)查報告說弧岳,人生平均只有7次決定人生走向的機會凳忙,兩次機會間相隔約7年,大概25歲后開始出現(xiàn)禽炬,75歲以后就不會有什么機會了涧卵。這50年里的7次機會,第一次不易抓到腹尖,因為太年輕艺演;最后一次也不用抓,因為太老桐臊。這樣只剩5次,這里面又有兩次會不小心錯過晓殊,所以實際上只有3次機會了断凶。】
參考文章
【1】Java中的動態(tài)和靜態(tài)編譯
【2】動態(tài)編譯和靜態(tài)編譯及Java執(zhí)行
【3】動態(tài)生成java巫俺、動態(tài)編譯认烁、動態(tài)加載
【4】java筆記十一:動態(tài)編譯
【5】Java學習之-動態(tài)編譯-DynamicCompile_反射調(diào)用
【6】Java動態(tài)編譯
【7】編寫高質(zhì)量代碼:改善Java程序的151個建議
其他
如果有帶給你一絲絲小快樂,就讓快樂繼續(xù)傳遞下去介汹,歡迎點贊却嗡、頂、歡迎留下寶貴的意見嘹承、多謝支持窗价!