TIJ-4Edition-初始化與清理
1、構造器保證初始化
沒有定義構造器時,編譯器會生成一個預設構造器(無參構造器);但是,當自己定義了有參構造器時,編譯器不會生成預設構造器,呼叫new時,必須傳入匹配的引數。
2、方法過載
每個過載的方法都具有獨一無二的引數列表(型別、順序)。
3、this關鍵字
呼叫物件方法時,編譯器把物件的引用this作為第一個引數傳入了方法內部(除了static方法),並在呼叫類方法時自動補上this。
(python類方法的引數列表的第一個引數也是當前物件的引用,需要顯示定義,但呼叫時由編譯器傳入)
4、static關鍵字
static修飾的欄位、方法屬於類而不屬於物件,因此,其內部沒有this引用。除非顯示的傳入物件引用,不然無法static方法內部不能呼叫非靜態方法。
5、finalize()方法
一旦GC打算回收物件佔用的空間,將首先會呼叫物件的finalize()方法(此特性可以用來驗證物件是否真正終結)。
能否將finalize()當解構函式使用? 不能!
1、GC會回收無用物件,但是其回收的時機是不確定的。
2、垃圾回收只與記憶體有關,其他清理工作必須自己建立普通方法來完成(如螢幕上繪製內容的清除)。
finalize()方法有何用?
在使用Native(本地)方法的情況下,其他使用其他語言分配的記憶體空間無法由GC回收,這時就要使用finalize()方法進行釋放。
6、GC工作原理
引用計數:當有引用指向物件時,計數加一;引用離開作用域或置為null時,計數減一。計數值減為0時,物件被清理。(出現迴圈引用時就完蛋啦)。
對任何“活著的”物件,一定能夠追溯到其存活在堆疊或靜態儲存區中的引用。反過來,從堆疊或靜態儲存區中的引用開始,遍歷到的所有物件都是“活的”。
停止-複製方法:停止程式執行,然後遍歷所有物件,將物件從當前堆複製到另一個堆,沒有被複制的就是垃圾。(代價很大,但是能實現記憶體緊縮效果)
標記-清掃:遍歷,並給物件設標記。等標記工作完成後再清理。不會產生複製操作,在垃圾很少是速度很快。
自適應技術:
記憶體分配以較大的塊為單位,物件較大則可以佔據單獨的塊,停止-複製方法可以往廢棄的塊中拷貝物件。
如果所有物件都很穩定,垃圾較少時,則採用標記-清理方法。
同時,跟蹤標記-清理效果,碎片多時切換回停止-複製方法。
7、成員初始化
保證所有變數在使用前都能得到恰當的初始化。區域性變數以編譯時錯誤的方式來保證。
類變數有初始值,該初始值由系統規定,在類載入時初始化。
怎麼給變數賦初值?
1、定義類變數時直接賦初值,定義順序決定了初始化順序,注意不要前向引用。
2、構造器初始化。儘管我們在構造器裡指定了類變數值,但是類載入時的自動初始化仍然會在構造器之前完成。
3、靜態變數初始化。靜態初始化只會在類的Class物件首次載入時進行。
4、顯示的靜態初始化,即在static程式碼塊裡進行初始化。也是在Class物件載入時執行。
5、非靜態例項初始化,即在程式碼塊裡,在構造器之前執行。
陣列初始化:
編譯器不允許指定陣列大小。為了給陣列分配空間,使用陣列之前,必須進行初始化。
淺拷貝:只是複製了引用,即執向了同一個地址,資源只有一份。
深拷貝:資源被複制,分配了新的空間。
可變引數列表:
1、將引數設為Object陣列,但是,傳參時要自己打包。
2、使用可變引數語法,該語法也適用於其他型別,基本型別也可(自動打包)。
底層原理是編譯器幫我們進行打包。
儘量只在過載方法的一個版本上使用,以免造成混亂,編譯器無法分派。
列舉型別:
在建立enum時,編譯器會會自動建立toString()、ordinal()、static value() 方法。
列舉和switch搭配食用效果更佳哦。