java 編譯原理 字符串_Java編譯原理(javac)

Java中的編譯分為兩個部分:

源碼文件編譯成字節碼文件(前端編譯)

字節碼文件被虛擬機加載以后編譯成機器碼(后端編譯)

對于開發來說接觸的一般都是第一個步驟也就是源碼編譯成字節碼文件(class文件),第二個步驟開發幾乎不會接觸,因為這是虛擬機在運行過程中自己做的一些編譯流程,將字節碼轉換成可被虛擬機識別執行的機器碼。

62c1b905a316fd95dfa95bd2736c3d2d.png

1. 前端編譯

前端編譯大致主要有以下流程:

對源文件進行詞法分析產生字符流

對字符流進行語法分析產生抽象語法樹

對語法樹進行語義分析,確保語義正常

語義分析通過以后生成中間代碼(字節碼)

下面我們站在javac的角度上看,編譯過程大致分為:

解析與填充符號表

插入式注解處理器的處理注解

語義分析與字節碼的生成

490f347eedd356bc7c8353b8f80c09b7.png

上述3個過程會包含前段編譯4個步驟的所有流程,下面我們看一下這個3個步驟需要做什么。

2. 解析與填充符號表

2.1 解析

2.1.1 詞法分析

Java源文件是由一個個字符構成,但是編譯器所能識別的是Token(標記)。我們需要通過詞法分析來將源文件中的字符流轉換成Token集合,這樣才能用于后續的語法分析。

int?a?=?b?+?c;

int是由3個字符構成,但是對于詞法分析來說,這三個字符會被解析成一個Token(標記)。

詞法分析主要由com.sun.tools.javac.parser.Scannaer類來實現。

2.1.2 語法分析

根據Token集合生成抽象語法樹,語法樹是一種用來表示程序代碼語法結構的表現形式,語法樹的每一個節點都代表著程序代碼中的一個語法結構,例如包、類型、修飾符。

package?jvm;

/**

*?@author?sh

*/

public?class?ClassTest{

public?int?add(int?a,?int?b){

return?a?+?b;

}

}

語法分析主要有com.sun.tools.javac.parser.Parser類來實現。

上述這段代碼生成的抽象語法樹如下(IDEA ?JDT AstView插件可以查看抽象語法樹):

a3e3a8e98b74de80df6753cfd152e2b3.png

上述抽象語法樹在Java中使用com.sun.tools.javac.tree.JCTree類來表示,之后所有的操作均建立在抽象語法樹之上。

2.2 填充符號表

結束了詞法分析和語法分析以后,下一步就是填充符號表。符號表中信息可以用在語義分析過程中的檢查和產生中間代碼

3. 注解處理器

注解處理器在編譯期間對注解進行處理,可以讀取、修改、添加抽象語法樹中的任意元素。如果注解處理器對語法樹進行了修改,編譯器將會回到解析和填充符號表的過程重新處理,直到注解處理器不再對語法樹進行修改為止,每一次循環稱為一個Round。

4. 語義分析和字節碼生成

4.1 語義分析

語義分析主要是對程序上下文進行檢查,如變量類型檢查。

語義分析主要包含兩個步驟:

標注檢查

數據及控制流分析

4.1.1 標注檢查

標注檢查主要用來檢查變量是否已被聲明、變量與賦值之間的數據類型是否匹配。在標注檢查的步驟中還會實施常量折疊。

int?a?=?1?+?2;

上述代碼我們在語法樹上可以看到字面量1、2以及操作符+,在經過常量折疊步驟以后,會生成一個新的字面量3,在程序運行時a的值就是3,不會再消耗CPU進行計算。

4.1.2 數據及控制流分析

數據及控制流分析是對程序上下文邏輯進行驗證,檢查局部變量是否在使用前已經賦值、方法的每條路徑都有返回值、所有的受檢查異常是否被正確處理。

局部變量final類型的變量的不變性只能依靠編譯來保證,這是因為局部變量在常量池中沒有CONSTANT_Fieldref_info的符號引用,沒有訪問標志的信息,在運行期虛擬機并不確定局部變量是否是final,因此需要編譯期的保證。

4.2 字節碼生成

字節碼在生成之前,還需要進行最后一項工作解語法糖。

4.2.1 解語法糖

Java中的語法糖包括范型、變長參數、自動裝箱/拆箱、Lambda。

語法糖可以增加程序的可讀性、減少代碼量。

4.2.2 字節碼生成

字節碼生成是javac編譯的最后一個階段。字節碼生成階段不僅僅是把各個步驟生成的信息轉換成字節碼寫到磁盤,還進行了代碼的添加和轉換工作。

將static語句塊、static變量收斂到

方法中

將實例變量初始化、調用父類構造器收斂到

方法

程序優化,比如將字符串的+操作替換成StringBuilder的append

完成了語法樹的遍歷和調整以后,就會填充了所有信息的符號表交給com.sun.tools.javac.jvm.ClassWriter類,最后由該類的writeClass()方法輸出字節碼。

本期的Java前端編譯介紹到這,我們下期再見!!!

我是shysh95,希望可以和你專注技術的路上并肩作戰,長按識別或者掃碼關注微信公眾號,更多精彩文章!!!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/259582.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/259582.shtml
英文地址,請注明出處:http://en.pswp.cn/news/259582.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

sql2012一段時間無法連接報53錯誤

2019獨角獸企業重金招聘Python工程師標準>>> 解決方案 在sqlserver網絡配置下的msqlserver協議下改將ip3改成如下圖所示 轉載于:https://my.oschina.net/u/2511906/blog/840373

ICE第三篇------一些疑難點

1 間接代理 參考http://blog.sina.com.cn/s/blog_53e8499c0100lkoo.html IceGrid用于支持分布式網絡服務應用,一個IceGrid域由一個注冊表(Registry)和任何數目的節點(Node)構成。注冊表(Registry)和節點(Node)一起合作…

windows phone 8 使用頁面傳對象的方式 實現頁面間的多值傳遞

在做windows phone 開發的時候,會經常碰到頁面間之間的跳轉和傳遞數據,如果傳遞的值不多,只有兩三個,我們通常使用NavigationService.Navigate(new Uri("頁面名? Name“”&ID“ ”, UriKind.Relative)); 要是碰到要傳遞…

php生成圖片驗證碼代碼,PHP生成圖片驗證碼以及點擊切換的代碼

這篇文章主要介紹了PHP生成圖片驗證碼實例,同時介紹了點擊切換(看不清&#xff1f;換一張)效果實現方法,需要的朋友可以參考下這里來看下效果:現在讓我們來看下 PHP 代碼<?php session_start();function random($len) {$srcstr "1a2s3d4f5g6hj8k9qwertyupzxcvbnm&quo…

python 時間日期處理

refer to : http://www.wklken.me/posts/2015/03/03/python-base-datetime.html#datetime-string http://www.cnblogs.com/65702708/archive/2011/04/17/2018936.html http://www.runoob.com/python/python-date-time.html 轉載于:https://www.cnblogs.com/qingyuanjushi/p/640…

php 字符型轉變為數值,php怎么把字符串轉換為數值?

php怎么把字符串轉換為數值&#xff1f;下面本篇文章給大家介紹一下PHP把字符串轉換為數值的方法。有一定的參考價值&#xff0c;有需要的朋友可以參考一下&#xff0c;希望對大家有所幫助。PHP中的字符串可以很容易地轉換成數值(float / int / double類型)。在大多數用例中&am…

解決rspec 生成報告時報utf-8錯誤的方法

找到gems\1.9.1\gems\rspec-core-2.14.3\lib\rspec\core\formatters\snippet_extractor.rb文件中的第27行&#xff1a; 在這邊記錄一下&#xff0c;防止以后再遇到。。。出現這個原因是因為ruby文件用utf-8格式的&#xff0c;但是源碼都是GBK處理的&#xff0c;找到\lib\ruby\…

aspose.words復制插入同一word文檔中的某個頁面

選擇word模板 Document doc new Document(Server.MapPath("~\\templet") "\\" name.Name);doc.MailMerge.CleanupOptions doc.MailMerge.CleanupOptions & ~MailMergeCleanupOptions.RemoveUnusedRegions;DocumentBuilder builder new DocumentBu…

開源游戲服務器C#

https://github.com/ScutGame/Scut/wiki轉載于:https://www.cnblogs.com/porter/p/6408955.html

EFProf Entity Framework Profile 工具

SQL Server Profiler用來跟蹤應用程序發送到SQL Server中的SQL語句&#xff0c;用于檢測性能&#xff0c;查找問題。Entity Framework 也有它的跟蹤工具EFProf&#xff0c;用于跟蹤Entity Framework發送到SQL Server中的SQL語句。 首先在代碼中添加對程序集HibernatingRhinos.P…

php面試中的問題,十個值得深思的PHP面試問題

十個值得深思的PHP面試問題過來人在以往的面試中總結的10個值得深思的 PHP 面試問題&#xff0c;希望對你現在的面試有用&#xff0c;少走彎路&#xff0c;更多內容請關注應屆畢業生網!Q1第一個問題關于弱類型$str1 yabadabadoo;$str2 yaba;if (strpos($str1,$str2)) {echo &…

Android中ExpandableListView控件基本使用

本文採用一個Demo來展示Android中ExpandableListView控件的使用&#xff0c;如怎樣在組/子ListView中綁定數據源。直接上代碼例如以下&#xff1a; 程序結構圖&#xff1a; layout文件夾下的 main.xml 文件源代碼例如以下&#xff1a; <?xml version"1.0" encodi…

【暴力】Codeforces Round #398 (Div. 2) A. Snacktower

題意不復述。 用個bool數組記錄一下&#xff0c;如果某一天&#xff0c;當前剩下的最大的出現了的話&#xff0c;就輸出一段。 #include<cstdio> using namespace std; int n; bool vis[100010]; int main() { // freopen("a.in","r",stdin);scanf(&…

javascript的對象創建模式---命名空間模式

javascript中對象的概念是很普遍的&#xff0c;對象是是對象&#xff0c;數組是對象&#xff0c;函數也是對象&#xff0c;字符串其實也是對象。常見的對象創建方法有對象字面量、構造函數創建。我們先來看看對象的創建還有哪些更高級的模式。 一、命名空間模式 二、模塊模式 三…

把Liststring集合,編程string,并以“,”號分割

List<int> roleIdList GetRoleIdList(user.ID); string roleIdsStr ""; if (roleIdList ! null) {roleIdsStr string.Join(",", roleIdList); } 轉載于:https://www.cnblogs.com/lijingran/p/6420364.html

武林外史java游戲,武林外史_網絡游戲專區_騰訊游戲頻道

1 、武師用防御工具1) 武衛類> 用土布制作的防護工具。階段圖片名稱說明1武威帶所需功力值所需力量所需技藝所需體力所需智能所需敏捷性防御力防御成功率8013013021 %武威甲所需功力值所需力量所需技藝所需體力所需智能所需敏捷性防御力防御成功率4160150021 %武威長褲所需功…

簡單實現KeyChain實例

目錄結構如下&#xff1a; AppDelegate.m 1 //2 // AppDelegate.m3 // KeyChain4 //5 // Created by apple on 14-12-26.6 // Copyright (c) 2014年 ll. All rights reserved.7 //8 9 #import "AppDelegate.h" 10 11 interface AppDelegate () 12 13 end 14 1…

Oracle 建立包 和 包體

--創建包create or replace package pac_stuastype cur_stu is ref cursor;procedure getStu(i in number,cur_stu out cur_stu);end pac_stu;--創建包體create or replace package body pac_stuasprocedure getStu(i in number,cur_stu out cur_stu)asnums number(10);begins…

alibaba fastjson

JSON解析器fastjson&#xff08;阿里巴巴出品&#xff0c;版本1.1.33&#xff09; import com.alibaba.fastjson.JSON; public static final Object parse(String text); // 把JSON文本parse為JSONObject或者JSONArraypublic static final JSONObject parseObject(String text)…

matlab 讀取excel一列,讀取excel中的數據把第一列相同的所有行數據輸出成一個excel...

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓284 1113436773300.00 1113436773.30 44.55284 1113436773400.00 1113436773.40 44.55284 1113436773500.00 1113436773.50 44.55284 1113436773600.00 1113436773.60 44.55284 1113436773700.00 1113436773.70 43.77284 111343677…