Java編程思想讀書筆記第五章: 初始化和清理

方法的重載

  • 重載方法可以通過參數列表進行區分,包括參數的類型,數量不同,如下所示
void driver(int i);
void driver(short i);
void dirver(int i, short i);
  • 參數類型爲基本類型,如果形參類型小於實參,形參類型將會被提升,反之形參需要強轉成比實參小的類型,如下所示, 調用short方法,i需要被強轉,j則變成了short類型
void driver(short prams);

int  i= 5;
driver((short)i);
byte j = 0;
driver(j);
  • 返回值不一樣,不能區分重載方法,如果我們按照下面這麼調用,編譯器根本不知道你調用的是哪個方法。
void f();
int f();

f();


this關鍵字的用法

  • 在方法中可以調用當前的類的成員變量或者方法,不過一般不建議這麼使用
this.a = 10;
this.f();
  • 在方法返回值中被使用,表示返回當前對象引用,可以對同一個對象執行多次操作,如Rxjava中的流式調用
public Car {
    Car driver() {
        prinf("dirver");
        return this;
    }
    
    Car stop() {
        printf("stop");
        return this;
    }
}

Car car = new Car();
car.driver().stop();
  • 構造器調用構造器,如果類中有多個構造器可以使用this調用其他構造器,只能在構造器中使用,並且只能調用一個構造器
public Car {
    public car() {
        this(5);
    }
    
    public car(int i) {
        print(i);
    }
}
  • 不要過於使用this關鍵字,比如在一個類中,調用類一個方法中調用另外一個方法,因爲編譯器能幫你自動添加,只有當明確指出當前對象的引用時,才使用this關鍵字。
public class A {
  void f() {
    this.p();//不要這麼用
    p(); //推薦
  }
  void p() {

  }
}


成員初始化

  • 可以在定義成員變量處就爲其指定初始值,基本變量會被默認賦予初值,比如
public Car {
    int i = 5;
    People people = new People();
}
  • 構造器初始化, 比如
public Car {
    int i;
    public Car() {
    }
}
  • 調用順序,先指定初始化,後構造函數初始化,如果指定了初值後,後構造器被調用,則值會被覆蓋,比如,i 先被賦值5, 後調用構造器,i變成了10
public Car {
    int i = 5;
    public Car() {
        i = 10;
    }
}


靜態數據初始化

  • 靜態數據可以通過上述兩種方法初始化,只要類被加載,就會被初始化,比如調用Car.j, 這時i,j, people 都會被初始化,如果不訪問Car類,數據就永遠不會被初始化
public Car {
    public static int j = 20;
    public static int i = 10;
    staic People pleple = new People();
}
  • 靜態數據只會被初始化一次,比如按照如下方法進行調用,輸出分別是10和11,可以看出即使new了一個新的Car對象,也不會再去對i重新賦值了
class Car {
    public static int i = 10;
    public void add() {
        i++;
    }
}

Car car1 = new Car();
print(Car.i);
car1.add();
Car car2 = new Car();
print(Car.i);

//output 10, 11


對象創建過程

  • 首先會加載Car.class文件,有關靜態變量都會被初始化。
  • new Car()對象,在堆上分配足夠的內存空間,並且清空這塊存儲空間,所有的基本類型都會被賦初值,比如int會被賦值爲0。
  • 執行所有變量指定初始化動作,也是在字段定義處。
  • 執行構造函數。
class Car {
    public static int i = 10;
    int j = 20;
    public car() {
        printf("init");
    }
}

Car car = new Car()


顯示靜態初始化

  • 可以使用static {}構建靜態代碼塊,可以裏理解成由多個靜態初始化動作組成。需要注意的是在靜態代碼塊中不論是調用變量還是方法都必須是靜態的。
  • 靜態代碼塊僅執行一次,執行時機是在首次訪問該類的時候,如new一個對象,訪問該類的成員變量。
public class Spoone
{
    static i;
    staic {
      i = 10;
      f();
    }
    public static f() {
      System.out.println(i);
    }
}

Spoone.i;
Spoone s = new Spoone();

非靜態實例初始化

  • 用一個{}構建非靜態實例代碼塊,當對象被new時就會被調用,在構造函數之前被調用,無論調用哪個構造函數都會調用該代碼塊
class Mug {
  {
    print("f(" + marker + ")");
  }
}

數組初始化

  • 數組的兩種初始化方式 , 第一種方式只能定義在聲明數組變量的地方。第二種形式可以定義在任何地方。
int[] a = {1,2,3,5};
Integer[] b = new Integer[5]; 
  • 可變參數,調用時可以傳遞任意數量參數(包括0),使用方式如下, 注意如果如果出現方法重載,當不傳入任何參數時,讓人很難弄清楚到底調用的是哪個函數,代碼可讀性就變得很差,所以最好在某個方法中添加一個非可變參數作爲區分。
void f (String... args) {
}

void f() {
}

f("1","2","3");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章