計算機只能識別機器碼0101...編程語言->能執行的機器碼 須要通過 預處理->編譯->彙編->連接->機器碼
過程。一個語言處理系統的示意圖以下:java
編譯器 是將源語言程序一次性翻譯成一個等價的,用目標語言編寫的程序。還存在另外一種常見的語言處理器,解釋器:它是逐個語句的執行源語言程序。由一個編譯器產生的目標語言程序一般比一個解釋器快,但解釋器的錯誤診斷效果一般更好。編程
Java語言處理器結合了編譯和解釋的過程。一個.Java
源程序首先被編譯爲.class
字節碼文件,被加載到虛擬機中,而後由虛擬機將字節碼翻譯成機器碼。安全
虛擬機的好處在於:一旦一個程序被轉換成 Java 字節碼,那麼它即可以在不一樣平臺上的虛擬機實現裏運行。實現一次編寫,處處運行。另一個好處是它帶來了一個託管環境。這個託管環境可以代替咱們處理一些代碼中冗長並且容易出錯的部分,如自動內存管理與垃圾回收。編程語言
在Hotspot中,虛擬機翻譯字節碼有兩種方式:工具
1.解釋執行
即逐條將字節碼翻譯成機器碼並執行。spa
2.即時編譯
即將一個方法中包含的全部字節碼編譯成機器碼後再執行。插件
前者的優點在於無需等待編譯,然後者的優點在於實際運行速度更快。HotSpot 默認採用混合模式,綜合瞭解釋執行和即時編譯二者的優勢。它會先解釋執行字節碼,然後將其中反覆執行的熱點代碼,以方法爲單位進行即時編譯。命令行
即時編譯創建在程序符合二八定律的假設上,也就是百分之二十的代碼佔據了百分之八十的計算資源。翻譯
好了,裝X結束。3d
阿姨知道的編譯知識全在上面了。。(っ╥╯﹏╰╥c)
如題,下面咱們來看一下讓Java項目運行起來咱們能作什麼。
咱們能作的很簡單,固然不是寫虛擬機。咱們只須要:
1.執行command javac
,將.Java文件變爲.class文件。
2.執行command java
,讓.class文件運行起來。
也就是 執行command :)
Java程序能夠經過java命令運行.class文件或運行可執行Jar文件。
咱們先看第一種方式:從Hello World開始。
Step1:編寫Java文件
Step2:執行 command javac
將.Java文件變爲.class文件
小貼士:class文件的全路徑名是包名目錄+ 類文件名。
Step3:執行 command java
運行.class文件
神奇,咱們沒有用IDE讓Java程序運行起來了 :)
小夥伴先別噴老阿姨,哪特麼有這麼簡單的Java項目啊。。咱們工做中用的明明都是Jar文件啊...
Jar文件咋運行啊!!
Jar文件是基於ZIP文件格式的一種文件格式,它將大量的Java類文件、相關的元數據和資源(文本、圖片等)文件聚合到一個Jar文件中,此外還包含一個可選的META-INF文件夾。這個文件夾下的文件或文件夾主要用來打包和擴展配置信息,包括安全,版本,擴展程序和服務等。如MANIFEST.MF文件定義了擴展和打包的相關數據信息。
一個Jar文件一般在項目中用做第三方類庫使用,也是項目構建的一部分。
生成一個Jar文件大體分爲兩步:
1.將源文件編譯爲.class文件
2.經過 command jar
命令將.class文件,資源文件等等打成一個文件格式的Jar文件。
咱們以一個SbDemo項目爲例來看Jar文件的打包和運行。項目目錄結構以下:
Test2.java中調用了Test1.java的方法,
咱們須要先將Test1.java編譯並打成一個Test1.jar文件,而後經過Test1.jar將Test2.java編譯並打成一個可執行的Test2.jar文件。
可執行和不可執行的Jar文件 區別在因而否在Jar文件中指定了main方法的入口,咱們後面再看。
Step1:Test1.java的編譯
Step2:將編譯後的classes/com/Test1.class文件打成一個Test1.jar包
Java中和jar包相關的命令是jar命令
,生成一個jar包咱們須要定義信息文件(manifest-file),它能夠定義所生成jar包的classpath類搜索路徑,jar包的入口類等等。能夠理解爲與Jar包相關的元數據配置信息。Step2.1 書寫信息文件
這裏咱們使用resources/manifest-test1.text文件做爲信息文件
是的,Test1.java太簡單了,就是打成一個可被他人引用的jar包,信息文件不重要。Step2.2 執行打包命令
Step3. 編譯Test2.java文件
由於Test2.java中引用了com.Test1類,因此咱們須要在編譯時指定Classpath路徑。
Classpath:顧名思義,是指待編譯類依賴的類所在路徑位置。咱們能夠經過 javac 的 -cp 參數指定。
關於編譯時classpath的值優先級以下:
-classpath or -cp
參數指定了類路徑值,則優先級最高。這裏咱們使用-cp指定Test1.jar所在位置
能夠看到classes目錄下已經生成了com2/Test2.class文件了。
Step4. 將編譯後的Test2.class和它依賴的Test1.jar一塊兒打成一個可執行的Jar包
Step4.1 書寫信息文件
這時候咱們使用信息文件resources/manifest-test2.text文件指定這些信息
Step4.2 執行Jar包生成命令
能夠看到在lib目錄下生成了Test2.jar
Step5.運行咱們的可執行Jar
大功告成了,咱們的SbDemo項目Run起來了...
固然實際項目不可能人肉編譯,打包。咱們須要經過Maven/Gradle等構建工具,幫助咱們管理代碼之間的Jar包依賴,構建,部署...咱們可能大多時候經過點一下IDE就託管了Maven的構建部署命令。
拿Maven舉例子,Maven首先定義了一套項目結構,咱們按照它的結構書寫代碼,引入各個模塊所須要的Jar包依賴。而後Maven能夠經過本身的生命週期管理項目的清理,構建,打包,部署階段。每一個階段有對應的Maven插件執行相應的目標。IDE又整合了Maven,使咱們經過點吧點吧按鈕就完成了項目的運行。
可是當一個項目並無按照規範的構建工具結構搭建,或者項目沒有成功運行報錯時,瞭解Java實際的編譯運行過程會對理解、解決這類問題有所幫助。
好啦,限於篇幅,阿姨先不講這些年Maven躺過的坑了,有想看的嗎?關注,在看,轉發
三連回應下 >-<
參考資料:
[1].《編譯原理》序 (゚´ω`゚)゚
[2].https://time.geekbang.org/column/article/11289