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