瘋狂Java程式設計師的基本素養學習筆記
學習一門技術,就要深入,投身一門職業,就要專注。作為一名Java程式設計師,不僅要知道怎麼去用這些技術、框架,而且要知道這些技術、框架是怎麼執行的、怎麼實現的。知其然而知其所以然。學習不能浮躁,循序漸進。
一、陣列及其記憶體管理
棧記憶體、堆記憶體、方法區
問題:
Java中,宣告並建立陣列的過程中,記憶體是如何分配的?
Java陣列的初始化方式有哪幾種?
基本型別陣列和引用型別陣列,在初始化時的記憶體分配機制的區別?
陣列,複合結構,Java語言的陣列變數是引用型別的變數。Java語言是典型的靜態語言,Java陣列也是靜態的,陣列初始化之後,所佔的記憶體空間、長度是不可變的,必須經過初始化後才能使用。
- 初始化方式
靜態初始化,顯示指定每個陣列元素的初始值,由系統決定陣列長度
動態初始化,只指定陣列長度,系統為陣列元素分配初始值
注意:靜態初始化和動態初始化不能同時使用,即不能同時指定陣列的長度和為每個陣列元素分配初始值。
Java陣列變數是引用型別的變數,陣列變數並不是陣列本身,它指向堆記憶體中的陣列物件(相當於指標)
Java是強型別語言,JavaScript是弱型別語言。
Java程式中的引用變數並不需要經過所謂的初始化操作,需要進行初始化的是引用變數所引用的物件
- 基本型別的陣列,陣列元素的值直接儲存在對應的陣列元素中
int [] a;
方法棧中定義一個a陣列變數,引用型別的變數,並未指向任何有效的記憶體,沒有真正指向實際的陣列物件,因此還不能使用陣列物件。
a = new int[]{2,1,3};
靜態初始化,系統決定長度,a指向堆記憶體空間。
注意:所有區域性變數都放在棧記憶體中儲存,即存在各自的方法棧記憶體中。引用型別的變數所引用的物件總是儲存在堆記憶體中。堆記憶體中的物件通常不允許直接訪問。main方法宣告的變數都屬於區域性變數,故都儲存在main方法棧區中。
Runtime異常:NullPointerException(空指標異常),當通過引用變數來訪問例項屬性,或呼叫非靜態方法時,如果該引用變數還未引用一個有效的物件,程式就會引發NullPointerException執行時異常。
- 引用型別陣列,陣列元素裡儲存的還是引用,它指向另一塊記憶體,該記憶體儲存了該引用變數所引用的物件
注意:Java語言避免訪問堆記憶體中的資料可以保護程式更加健壯,如果程式直接訪問並修改堆記憶體中的資料,可能會破壞記憶體中的資料完整性,導致程式Crash。
Java允許將多維陣列當成一維陣列處理。通過陣列的length屬性獲取陣列的長度:前提是把N維陣列當成陣列元素N-1維陣列的一維陣列
二、物件及其記憶體管理
問題:
為什麼要建立這麼多的例項?
物件建立對系統的開銷
Java物件的記憶體分配機制
可以參考:
http://imtianx.cn/2016/11/19/java%20%E7%9F%A5%E8%AF%86%E4%B9%8B%20%E5%AF%B9%E8%B1%A1%E5%8F%8A%E5%85%B6%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86/
Java記憶體管理
記憶體分配:特指建立Java物件時JVM為該物件在堆記憶體中所分配的記憶體空間
記憶體回收:當Java物件失去引用,變成垃圾時,JVM的垃圾回收機制自動清理物件,並回收該物件所佔用的記憶體
注意:Java程式依然會有記憶體洩漏
JVM的垃圾回收機制由一條後臺執行緒完成,非常消耗效能。建立沒用的物件,壞處:
不斷分配記憶體使得系統中可用的記憶體減少
大量已分配記憶體的回收使得垃圾回收的負擔加重
(都會降低程式的執行效能)
- Java程式的變數
成員變數(類體內定義的變數):非靜態變數/例項變數,靜態變數/類變數
區域性變數:形參、方法內的區域性變數、程式碼塊內的區域性變數,區域性變數的作用時間很短,儲存在棧記憶體中
注意:
static就是一個標誌,static只能修飾類裡的成員,不能修飾外部類,不能修飾區域性變數、區域性內部類,static的作用是將例項成員變為類成員
Java中定義成員變數時要注意前向引用,同一個JVM中,每個類對應一個Class物件,但每個類可以建立多個Java物件
類也是物件,所有類都是Class的例項。每個類初始化完成之後,系統都會為該類建立一個對應的Class例項,程式可以通過反射獲取對應的Class例項。
Person.class;
Class.forName(“Person”);
類的例項也可以訪問類變數,這樣設計似乎有些不合理。類的物件訪問類變數本質也是轉換為類訪問類變數
- 例項變數的初始化時機(非靜態變數)
每次建立Java物件都需要為例項變數分配記憶體空間,對例項變數執行初始化
1、定義例項變數時指定初始值
2、非靜態初始化塊中對例項變數指定初始值
3、構造器中對例項變數指定初始值
(第1/2方式比第3方式更早執行,1/2方式執行順序與原始碼中的排列順序相同)
分析:
double w = 2;
double w;建立Java物件時系統根據該語句為物件分配記憶體
w = 2;這條語句會在Java類的構造器中執行
- 類變數的初始化時機
每個JVM對一個Java類只初始化一次,為該類的類變數分配記憶體空間,指定預設值。
1、定義類變數時指定初始值
2、靜態初始化塊中對類變數指定初始值
(1/2方式的執行順序與排列順序相同)
建立Java物件時,程式總會依次呼叫每個父類的非靜態初始化塊、構造器執行初始化,然後才呼叫本類的非靜態初始化塊、構造器執行初始化
注意:
super呼叫用於顯示呼叫父類構造器,this呼叫用於顯示呼叫本類中另一個過載的構造器。super和this呼叫都只能在構造器中使用,都必須作為構造器的第一行程式碼
只能使用其中之一,而且只能最多隻能呼叫一次
- 子類與父類中的例項變數、方法的區別
一個Java物件可以擁有多個同名的例項變數,子類定義的成員變數並不能完全覆蓋父類中成員變數
當變數的編譯時型別和執行時型別不同時,通過該變數訪問引用的物件的例項變數時,該例項變數的值由宣告該變數的型別決定
- 父子例項的記憶體控制
Java繼承中對成員變數和方法的處理是不同的。
當通過變數呼叫方法時,方法的行為總是表現出它們實際型別的行為,訪問它們的所知物件的例項變數時,例項變數的值總是表現出變數所引用型別的行為。(方法可以被重寫,變數不存在重寫)
當子類使用public訪問控制修飾符,父類不使用public修飾符,才可以通過javap看到編譯器將父類的public方法直接轉移到子類中
子類物件的儲存記憶體中不存在父類物件,只存在一個子類物件,只是儲存了它所有父類所定義的全部例項變數。
Java程式中允許某個方法通過return this;返回撥用該方法的Java物件,但不能直接使用return super;甚至不允許直接將super當成一個引用變數使用。super關鍵字本身並沒有引用任何物件
1、子類方法不能直接使用return super;允許某個方法通過return this;返回撥用該方法的Java物件
2、甚至不允許直接將super當成一個引用變數使用。Super == a;引起編譯錯誤
子類中,一般用super.作為限定來修飾例項變數、方法
訪問父類的靜態變數/類變數,方式
1、使用父類的類名(推薦,程式碼可讀性)
2、使用super.限定來訪問
- final修飾符
1、final修飾的變數,賦值後,不能重新賦值
final例項變數:
必須顯示指定初始值
三種賦初始值的方式,都會抽到構造器中賦初始值(本質一樣)
final類變數:
必須顯示指定初始值
只能在定義時、靜態初始化塊中指定初始值
注意:
初始值在編譯時就被確定下來,系統不會在靜態初始化塊中對該類變數賦初始值
final修飾符定義“巨集變數”,定義時就賦初始值,編譯器會把程式中所有用到該變數的地方直接替換成值
對於final例項變數,只有在定義該變數時指定初始值才會有“巨集變數”的效果
對於final類變數,只有在定義時指定初始值才有“巨集變數”的效果
2、final修飾的方法,不能重寫
如果程式需要在匿名內部類中使用區域性變數,必須使用final修飾符修飾
在任何內部類中訪問的區域性變數都應該使用final修飾
此處內部類為區域性內部類,區域性內部類才可以訪問區域性變數,普通靜態內部類、非靜態內部類不可能訪問方法體內的區域性變數
內部類可能產生隱式的“閉包”,閉包將使得區域性變數脫離其所在的方法繼續存在
內部類會擴大區域性變數作用域的例項
3、final修飾的類,不能派生子類
相關文章
- 瘋狂的程式設計師程式設計師
- 書摘:瘋狂的程式設計師程式設計師
- 程式設計師的美:極致與瘋狂程式設計師
- OC語言瘋狂講義學習筆記C語言筆記
- 瘋狂的程式設計世界程式設計
- 程式設計師,修女也瘋狂嗎 (轉)程式設計師
- 程式設計師的職業素養(一)程式設計師
- 《程式設計師的職業素養有感》程式設計師
- 《程式碼整潔之道——程式設計師的職業素養》讀書筆記(一)程式設計師筆記
- 程式設計師的基本素質如何?程式設計師
- 轉贈《程式設計師的職業素養》程式設計師
- 黑馬程式設計師——Java學習筆記之⑦——“網路程式設計”程式設計師Java筆記
- 程式設計師該有的職業素養程式設計師
- 讀《瘋狂Java:突破程式設計師基本功的16課》之陣列與記憶體控制部分總結Java程式設計師陣列記憶體
- 瘋狂學習——DP!
- 《程式設計師的自我修養》-讀書筆記程式設計師筆記
- 讀書筆記 - 《程式設計師的自我修養》筆記程式設計師
- 論一個程式設計師的職業素養程式設計師
- java程式設計師程式設計筆試基礎學習Java程式設計師筆試
- 《程式設計師自我修養》讀書筆記程式設計師筆記
- 黑馬程式設計師——Java學習筆記之⑧——“Java新技術”程式設計師Java筆記
- 阿龍的學習筆記---《程式設計師自我修養-連結、裝載與庫》讀書筆記(二)筆記程式設計師
- 程式設計師的專業主義精神——評《程式設計師的職業素養》程式設計師
- 程式設計師的自我修養筆記之裝載程式設計師筆記
- 成長之路--論程式設計師的職業素養程式設計師
- 好程式設計師學習筆記:函式程式設計師筆記函式
- 面向切面程式設計之瘋狂的 Aspects程式設計
- 程式設計師職業素養之讀後感程式設計師
- 工作中最讓程式設計師瘋狂的5件事程式設計師
- 程式碼整潔之道:程式設計師的職業素養(十三)程式設計師
- Java學習筆記--網路程式設計SocketJava筆記程式設計
- 好程式設計師web前端培訓學習筆記Vue學習筆記一程式設計師Web前端筆記Vue
- 狂神說Java Web學習筆記_CookieJavaWeb筆記Cookie
- java-程式的基本結構(java 學習筆記 (1.1)) (轉)Java筆記
- 好程式設計師web前端培訓學習筆記Vue學習筆記之二程式設計師Web前端筆記Vue
- 《程式設計師的自我修養筆記之靜態連結》程式設計師筆記
- 為程式設計師開一劑提高職業素養的良方程式設計師
- Java程式設計師學習Rust程式設計 - infoworldJava程式設計師Rust