1. 程式人生 > >程式設計思想—初始化與清理

程式設計思想—初始化與清理

1.構造方法沒有返回值,與返回void是不同的,雖然new表示式確實返回了對新建物件的引用,但構造器本身並沒有任何返回值

2.方法過載根據方法引數的型別和數量不同進行區分,與方法的返回值和許可權修飾符無關。對於基本型別的方法過載,由於基本型別能夠自動從一個較小的型別提升到一個較大的型別,因此

  • 當入參型別小於引數宣告型別時,能夠自動提升(如入參為int,宣告為float,int會自動提升為float)
  • char有所不同,char會直接提升到int型別(不會轉為short)。
  • 當入參型別大於引數宣告型別時,必須通過型別轉換進行窄化轉換,否則編譯器會報錯。

3.this主要用於方法內部對當前物件的操作,它本身表示當前物件的引用,this還有以下用法

  • 當形參與實參同名時,使用this指定實參
  • this在構造器中呼叫其他構造器時,必須位於該構造器的首行

4.static

普通的方法、變數是屬於物件的,可以使用this呼叫,static修飾的方法、變數是屬於類的,無法使用this呼叫。

static修飾只能使用類去呼叫,且static方法裡無法呼叫非static方法。

5.finalize()

由於垃圾回收期只知道回收new分配的記憶體,其他記憶體不知道如何釋放,因此定義該方法,其功能假定為:

一旦垃圾回收器準備好釋放物件佔用的儲存空間,將首先呼叫其finalize()方法(java語言規範並不能保證該方法一定能及時的呼叫甚至無法保證被呼叫),並且在下一次垃圾回收動作發生時,才會真正回收物件佔用的記憶體。但java中的物件並非總是被垃圾回收

  • 物件可能不被垃圾回收
  • 垃圾回收並不等於析構
  • 垃圾回收只與記憶體有關

finalize()方法並不是普通的清理工作場所,它主要用於清理本地物件(非java程式碼),詳情點這裡

雖然不能只讓finalize函式進行清理工作,但它可以用於物件終結條件的驗證,例如

所有物件在被垃圾回收前都應該被checkin(一個方法),若某個物件忘記checkin,finalize方法里加入了對checkin的檢測,就能找出這個隱藏的問題。雖然finalize並不一定會被呼叫。

6.垃圾回收方法

引用計數法:一種很慢的垃圾回收方法。每個物件都含有一個引用計數器,當有引用連線至物件時,計數器+1,當引用離開作用域或被至為null時,計數器-1,當計數器歸零時,釋放空間。雖然計數開銷不大,但該開銷在整個程式生命週期中,且該方法對於迴圈引用(互動自引用)所需做的工作極大。

追溯思想:對任何活的物件,一定能最終追溯到其存貨在堆疊或靜態儲存區之中的引用。從堆疊和靜態儲存區開始,遍歷所有引用就能找到所有物件,能夠解決互動自引用物件組的問題。

停止-複製法:先暫停程式執行,將所有活的物件從當前對複製到另一個堆,沒複製過來的就是垃圾。複製過去後是一個愛著一個的,保持緊湊排列,有利於分配新空間。同時物件的移動也對導致引用的失敗,必須進行修正。該方法效率低,首先需要兩個堆來回折騰,空間度X2,其次當程式穩定後垃圾很少,仍會進行復制操作,浪費。

標記-清除法:對於一般的清楚而言慢,但若垃圾很少,則速度很快。它在遍歷物件時給活的物件進行標記,當標記全部完成後,開始清理。清理後空間並不連續。

自適應:當有大量物件需要清理時,採用停止-複製法;當穩定後切換到標記清掃;當堆空間出現很多碎片,切換回停止-複製法。

7.初始化

區域性變數若未初始化,會產生編譯錯誤;

類的資料成員是基本型別,編譯器會自動給它們一個初始值。

靜態初始化只會執行一次!

父類靜態變數/靜態初始塊 > 子類靜態變數 /靜態初始塊 > 父類成員變數/非靜態初始塊 > 父類構造器 > 子類成員變數 /非靜態初始塊 > 子類構造器

變數和初始化塊的先後取決於程式碼順序。

陣列花括號初始化只能出現在建立陣列的地方,且在花括號中,最後一個逗號是可選的,即可以出現

int[] a = {1,2,3,}的情況

可變引數列表:

    public void test(int... a){
        for (int s :a){
            System.out.println(s);
        }
    }
    public void testMain(){
        test(1,2,3);
    }

這裡int...a代表未知個數的int型別引數,a為陣列名。

該方法將過載變得複雜,但可以額外加入一些非可變引數來解決問題。

8.列舉

列舉例項是常量,因此用大寫字母表示。為了使用列舉,需要建立一個引用,將其賦值給某個例項。

toString()方法顯示列舉名字;ordinal()方法表明某個特定列舉常量的宣告順序(數字);static values()產生安卓宣告順序產生的陣列;

列舉可以用於switch。

switch(degree){
    case NOT: ...;break;
    case HOT: ...;break;
}