1. 程式人生 > >Java程式碼編譯過程簡述

Java程式碼編譯過程簡述

 

程式碼編譯是由Javac編譯器來完成, 這是由.java原始碼檔案轉為 .class二進位制位元組碼檔案的過程。

詳細過程:

       原始碼檔案*.java -> 詞法分析器 -> tokens流 -> 語法分析器 -> 語法樹/抽象語法樹 -> 語義分析器 -> 註解抽象語法樹 -> 位元組碼生成器 -> JVM位元組碼檔案*.class 

       Javac是一種編譯器,能將一種語言規範轉化成另外一種語言規範,通常編譯器都是將便於人理解的語言規範轉化成機器容易理解的語言規範

,如C/C++或者組合語言都是將原始碼直接編譯成目標機器碼,這個目標機器程式碼是CPU直接執行的指令集合。這些指令集合也就是底層的一種語言規範。

        Javac的編譯器也是將Java這種對人非常友好的程式語言編譯成對對所有機器都非常友好的一種語言。這種語言不是針對某種機器或某個平臺。怎麼消除不同種類,不同平臺之間的差異這個任務就由JVM來完成,而Javac的任務就是將Java原始碼語言轉化為JVM能夠識別的一種語言,然後由JVM將JVM語言再轉化成當前這個機器能夠識別的機器語言

       Javac的任務就是將Java原始碼編譯成Java位元組碼,也就是JVM能夠識別的二進位制程式碼,從表面看是將.java檔案轉化為.class檔案。而實際上是將Java原始碼轉化成一連串二進位制數字,這些二進位制數字是有格式的,只有JVM能夠真確的識別他們到底代表什麼意思。

 編譯器把一種語言規範轉化為另一種語言規範的這個過程需要哪些步驟? 回答這個問題需要參照《編譯原理》,總結過程如下:

        1)詞法分析:讀取原始碼,一個位元組一個位元組的讀進來,找出這些詞法中我們定義的語言關鍵詞如:if、else、while等,識別哪些if是合法的哪些是不合法的。這個步驟就是詞法分析過程。

        詞法分析的結果:就是從原始碼中找出了一些規範化的token流,就像人類語言中,給你一句話你要分辨出哪些是一個詞語,哪些是標點符號,哪些是動詞,哪些是名詞。

        2)語法分析:就是對詞法分析中得到的token流進行語法分析,這一步就是檢查這些關鍵詞組合在一起是不是符合Java語言規範。如if的後面是不是緊跟著一個布林型判斷表示式。

        語法分析的結果:就是形成一個符合Java語言規定的抽象語法樹,抽象語法樹是一個結構化的語法表達形式,它的作用是把語言的主要詞法用一個結構化的形式組織在一起。這棵語法樹可以被後面按照新的規則再重新組織。

        3)語義分析:語法分析完成之後也就不存在語法問題了,語義分析的主要工作就是把一些難懂的,複雜的語法轉化成更簡單的語法。就如難懂的文言文轉化為大家都懂的百話文,或者是註釋一下一些不懂的成語。

        語義分析結果:就是將複雜的語法轉化為簡單的語法,對應到Java就是將foreach轉化為for迴圈,還有一些註釋等。最後生成一棵抽象的語法樹,這棵語法樹也就更接近目標語言的語法規則。

        4)位元組碼生成:將會根據經過註釋的抽象語法樹生成位元組碼,也就是將一個數據結構轉化為另外一個數據結構。就像將所有的中文詞語翻譯成英文單詞後按照英文語法組裝文英文語句。程式碼生成器的結果就是生成符合java虛擬機器規範的位元組碼。

 

JAVA是解釋型語言還是編譯型語言?

概念:

  • 編譯型語言:把做好的源程式全部編譯成二進位制程式碼的可執行程式。然後,可直接執行這個程式。
  • 解釋型語言:把做好的源程式翻譯一句,然後執行一句,直至結束!

區別:

  • 編譯型語言,執行速度快、效率高;依賴編譯器、跨平臺性差些。如C、C++、Delphi、Pascal,Fortran。
  • 解釋型語言,執行速度慢、效率低;依賴直譯器、跨平臺性好。如Java、Basic.

   通俗的講,編譯語言是在編譯後可以直接執行,而解釋語言的執行需要一個解釋環境

    java很特殊,java程式也需要編譯,但是沒有直接編譯稱為機器語言,而是編譯稱為位元組碼,然後用解釋方式執行位元組碼。