1. 程式人生 > 其它 >TIJ-4Edition-初始化與清理

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搭配食用效果更佳哦。