java基础篇---第一天
今日開始在心中正式開始在培訓班開始培訓。一下是在培訓的過程中發(fā)現(xiàn)自己在自學過的過程中發(fā)現(xiàn)的問題。這篇是java基礎(chǔ)篇。
第一天
:
1)配置java環(huán)境變量
1、在系統(tǒng)變量中新建JAVA_HOME:jdk的地址。
2、在WIN10在Path中新添%Java_HOME%\bin
2)深入理解jvm與跨平臺原理
JVM也是一個軟件,不同的平臺有不同的版本。我們編寫的Java源碼,編譯后 會生成一種 .class 文件,稱為字節(jié)碼文件。Java虛擬機就是負責將字節(jié)碼文件翻譯成特定平臺下的機器碼然后運行。也就是說,只要在不同平臺上安裝對應(yīng)的JVM,就可以運行字節(jié)碼文件,運行我們編寫的Java程序。
而這個過程中,我們編寫的Java程序沒有做任何改變,僅僅是通過JVM這一”中間層“,就能在不同平臺上運行,真正實現(xiàn)了”一次編譯,到處運行“的目的。
JVM是一個”橋梁“,是一個”中間件“,是實現(xiàn)跨平臺的關(guān)鍵,Java代碼首先被編譯成字節(jié)碼文件,再由JVM將字節(jié)碼文件翻譯成機器語言,從而達到運行Java程序的目的。
3)java編譯原理
1.javac是什么?
(1)javac是一種編譯器,能夠?qū)⒁环N語言規(guī)范轉(zhuǎn)換成另一種用語言規(guī)范,通常編譯器是將便于人們理解的語言規(guī)范成機器容易理解的語言規(guī)范。
(2)javac的任務(wù)就是將java源代碼語言轉(zhuǎn)換成jvm能夠識別的語言,然后jvm將jvm語言再轉(zhuǎn)化成當前機器能夠識別的語言(這樣使得對開發(fā)者屏蔽與機器相關(guān)的細節(jié),并且使得語言的執(zhí)行與平臺無關(guān))
2.javac編譯器的基本結(jié)構(gòu)
(1)步驟:
<1>讀取源碼,進行詞法分析。也就是找出源碼字節(jié)中的關(guān)鍵字,識別出合法的關(guān)鍵字,最后得出一些規(guī)范化的Token(中文意思是“標記“、”象征”等)流。
<2>對Token流進行語法分析,檢查關(guān)鍵詞的組合是否符合語法,最后得到抽象的語法樹(語法樹是吧語言的主要此法用一個結(jié)構(gòu)化的形式組合在一起)
<3>進行語法分析,把難懂的,復雜的語法轉(zhuǎn)化成更加簡單的的語法(對計算機來說),最后得到一個注解過后的抽象語法樹
<4>通過字節(jié)碼生成器將經(jīng)過注解的抽象語法樹生成字節(jié)碼
(2)Javac的四大模塊:詞法分析器、語法分析器、語義分析器和代碼生成器
3.javac工作原理分析:(以openjdk源碼為例)
(1)詞法分析器:
其分析結(jié)果就是將這個類中的所有關(guān)鍵字匹配到Token類中的任何一項,最終得到Token流
<1>javac是如何分辨出一個個的Token?
javac進行詞法分析時會根據(jù)java語言規(guī)范來控制什么順序,在什么地方應(yīng)該出現(xiàn)什么Token(如對package的讀取,package語法規(guī)范上應(yīng)該是第一個token,那么在構(gòu)造javacParser的時候?qū)⒆x取這第一個token,然后往下就是讀取IDENTIFIER即是用戶定義的名稱,在讀取類名時如果遇到Token.Dot也就是‘.’將繼續(xù)往下讀,直到讀得完成類名即遇到Token.SEMI(“;”)為止)。也就是說,讀取每一個Token是由javacParser規(guī)定的而Token流的順序是符合java語言規(guī)范的
<2>如何得知當前讀到的Token是Token中的那一項,package就是Token.PACKAGE?
如何確定字符組合是一個Token的規(guī)則實在Scanner的nextToken方法中確定的,每調(diào)用該方法一次就會構(gòu)造一個Token,并且這些Token必然是Token中的任一個項。java中鎖由的字符集合都能找到Token中對應(yīng)的項,Keywords類負責把每個字符集合對應(yīng)到Token集合中,每一個字符集合都有一個Name對象,而Keywords會先把Token.name轉(zhuǎn)化成Name對象,然后建立token和name的對應(yīng)關(guān)系并保存在key數(shù)組中,而其他字符集將對應(yīng)到Token.Identifier(用戶定義的標識?)中。(也就是關(guān)鍵字會有對應(yīng)表,指定關(guān)鍵字的字符集會對應(yīng)到對應(yīng)的Token中,而沒找到的將當作用戶自定義的Identifier)
(2)語法分析器
語法分析器就是將Token流組裝成更加結(jié)構(gòu)化的語法樹,也就是將一個個的單詞組裝成語法樹
<1>每個語法樹上的語法節(jié)點都是JCTree的實例,語法樹的一些規(guī)則如下:
[1]每個節(jié)點都會實現(xiàn)一個xxtree接口,該接口繼承自com.sun.source.tree.Tree。如IfTree語法節(jié)點表示一個if類型表達式
[2]每個節(jié)點都是com.sun.tools.javac.tree.JCTree的子類并實現(xiàn)[1]中提及的接口,這個類的類名類似于JCxxx類,
[3]所有的JCxxx類都作為一個靜態(tài)內(nèi)部類定義在JCTree類中
<2>JCTree類中有如下三個重要的屬性項
[1]Tree tag:每個節(jié)點都會用一個整形屬性表示,別且每個節(jié)點的類型的數(shù)值都是前一個節(jié)點的類型數(shù)值加一(也就是這個屬性代表節(jié)點的類型,并且類型的數(shù)值是上一個節(jié)點類型的數(shù)值加一?)
[2]pos:表示語法節(jié)點在源文件中的起始位置,文件的起始位置為0,-1的話表示不存在
[3]type:表示這個語法節(jié)點是什么類型,如int、float還是String
<3>按照順序(與上述token流的順序相關(guān),也就是使用java語言規(guī)范控制順序?)讀取各個語法樹(子樹?)及其中的節(jié)點,最后把這些子樹加到頂層語法節(jié)點之下,也就是以package作為pid并且持有JCClassDecl語法節(jié)點的集合JCCompilationUnit
(3)語義分析器
<1>通過語法分析器獲得的語法樹還是十分粗糙的,還需要給類添加默認的構(gòu)造器,檢查變量使用前是否已經(jīng)初始化…等操作(檢查是否有語法錯誤在這一步?),而這些操作將由語義分析器完成
<2>具體實現(xiàn):
[1]主要由com.sun.tools.javac.comp.Enter類實現(xiàn)將java類中的符號(關(guān)于符號:轉(zhuǎn)載的一句話——“在java代碼中,一個類可能使用另外類或者接口的字段或者調(diào)用另外一個類的方法。在編譯的時候,class文件中是通過叫做"符號引用"的方式來實現(xiàn)的”。)輸入到符號表中:第一步將所有類中出現(xiàn)的符號輸入到自身的符號表,并將類符號、類的參數(shù)類型符號(泛型參數(shù)類型)、超類符號,繼承類型符號和繼承的接口類型符號都存儲到一個未處理列表中。第二步將這個未處理列表中的所有類都解析到各自的符號列表中。
[2]另外一種的Enter類還會為類 添加默認的構(gòu)造函數(shù)
[3]處理注解
[4]檢查語義的合法性和進行邏輯判斷,如:變量的類型是否匹配,變量在使用前是否初始化,能夠推導出泛型方法的參數(shù)類型,字符串常量的合并(常量折疊,會將一個字符串常量中的多個字符串合并成一個,如語句“String 是= “aa”+“bb”; “在語義轉(zhuǎn)換后會變成” String s =“aabb”; “,所以寫代碼的時候多個常量字符串相加的代碼其實會被優(yōu)化成一個字符串而不會產(chǎn)生多個)等
[5]數(shù)據(jù)流分析:如檢查變量使用前是否正確賦值(這里對比[4]主要是像String一樣的對象引用是否賦值,估計上面是針對int等基礎(chǔ)類型?),final變量是否不會被重復賦值,方法的返回值類型是否確定,檢查異常是否已捕獲或向上拋出,是否存在不會被執(zhí)行的語句,消除無效語句(如永遠為false的判斷),解除語法糖(如foreach改為標準for循環(huán),變量的自動轉(zhuǎn)換如Integer等基本類型的封裝類型與基本類型的賦值操作改為標準的操作內(nèi)部類的轉(zhuǎn)換(內(nèi)部類名改為”外部類名$內(nèi)部類名“),arsert語法的轉(zhuǎn)換等等)
(4)代碼生成器
<1>負責將結(jié)構(gòu)化的語義樹生成最終的java字節(jié)碼
<2>生成java字節(jié)碼主要經(jīng)過兩個步驟:
[1]將java方法中的代碼塊轉(zhuǎn)成符合JVM語法的命令形式,jvm的所有操作都是基于棧的,所有操作都必須經(jīng)過出棧和進棧來完成
[2]按照jvm的文件組織格式將字節(jié)碼輸出到以class文擴展名的文件中
4.設(shè)計模式解釋之訪問者模式
<1>其實上述的此法分析器、語法分析器,語義分析器,代碼生成器等都會多次遍歷語法樹,并進行處理,這其實是訪問這模式
<2>訪問這模式的設(shè)計初衷是為了將穩(wěn)定的數(shù)據(jù)結(jié)構(gòu)和變化多端的對數(shù)據(jù)結(jié)構(gòu)的操作解耦。
<3>轉(zhuǎn)載資料:“
訪問者模式是一種將算法與對象結(jié)構(gòu)分離的軟件設(shè)計模式。
總結(jié)
以上是生活随笔為你收集整理的java基础篇---第一天的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AutoCAD 2020安装失败(错误代
- 下一篇: Midjourney用户手册中文版详解模