1. 程式人生 > >Java程式設計思想ch5 初始化和清理

Java程式設計思想ch5 初始化和清理

5.1 用構造器初始化

    new 類名() 將建立和初始化,綁在一起。

5.2 方法過載

5.4 this關鍵字

class Banana{void peel(int i)}{}
public class BananaPeel{
    public static void main(String[] args){
        Banana a = new Banana(),b = new Banana();
        a.peel(1);
        b.peel(2);
        /*
            只有一個peel,編譯器是通過下面方式知道誰呼叫方法。
            編譯器將“所操作物件的引用”作為第一個引數傳遞給peel(),
            變成Banana.peel(a,1);
                Banana.peel(b,2);
                所以方法內部有一個物件的引用,用this來指代。
                this關鍵字只能在方法內部使用,表示對“呼叫方法的那個物件”的引用。
        */
} } 在非靜態方法內部可以直接呼叫該類的其他方法,會自動將this傳入。 因為呼叫該非靜態方法的時候已經傳入了物件的引用。

5.4.2 static的含義

static方法就是沒有this傳入的方法。在static方法內部不能直接呼叫非靜態方法,即不能像非靜態方法一樣直接呼叫該類的非靜態方法,因為沒有傳入物件。(但可以通過傳遞一個物件引用,用該引用來呼叫非靜態方法)。

5.7 構造器初始化

無法阻止自動初始化的進行。

    public class Counter{
        int i;
        Counter(){i=7
;} } // i先被初始化為0;再賦值為7;

5.7.1 初始化順序

變數定義即使散落方法定義間,仍舊會在任何方法(包括構造器)被呼叫之前得到初始化。

package Cha5;
import static tools.Print.print;
/**
 * Created by YL on 2017/9/7.
 */
class Window {
    Window(int marker){print("Window("+marker+")");}
}
class House{
    Window w1 = new Window(1);
    House(){
        print("House()"
); w3 = new Window(33); } Window w2 = new Window(2); void f(){print("f()");} Window w3 = new Window(3); } public class OrderOfInitialization{ public static void main(String[] args){ House h = new House(); h.f(); } }

靜態資料的初始化

沒有顯示寫出,但構造方法也是靜態的。

呼叫靜態方法和靜態域都要先載入這個類。
非靜態方法和域因為要通過物件來呼叫,在用構造器時,因為構造器是靜態,已經載入了類。

static 關鍵字不能用於區域性變數,只能作用於域。區域性變數是無法成為類的一部分的。

一個靜態域,沒有初始化:基本型別獲得預設值;物件引用為null。

package Cha5;
import static tools.Print.print;

class Bowl{
    Bowl(int marker){
        print("Bowl("+marker+")");
    }
    void f1(int marker){
        print("f1("+marker+")");
    }
}

class Table{
    static Bowl bowl1 = new Bowl(1);
    Table(){
        print("Table()");
        bowl2.f1(1);
    }
    void f2(int marker){
        print("f2("+marker+")");
    }
    static Bowl bowl2 = new Bowl(2);
}

class Cupboard{
    Bowl bowl3 = new Bowl(3);
    static Bowl bowl4 = new Bowl(4);
    Cupboard(){
        print("Cupboard");
        bowl4.f1(2);

    }
    void f3(int marker){
        print("f3("+marker+")");
    }
    static Bowl bowl = new Bowl(5);
}

public class StaticInitialization {
    public static void main(String[] args) {
        print("Creating new Cupboard() in main");
        new Cupboard();
        print("Creating new Cupboard() in main");
        new Cupboard();
        table.f2(1);
        cupboard.f3(1);
    }
    static Table table = new Table();
    static Cupboard cupboard = new Cupboard();
}

output:

/*程式由主函式開始執行,先初始化main函式所在類的變數,table和cupboard。初始化table要呼叫table建構函式,在此之前,要先初始化Table中靜態變數bowl1和bowl2,列印輸出的前兩行。
初始化順序是先靜態變數,後“非靜態”變數。*/

    Bowl(1)
    Bowl(2)
    // Table的建構函式
    Table()
    f1(1)
    // Cupboard類的靜態變數初始化。 
    Bowl(4)
    Bowl(5)
    // 非靜態變數後初始化。
    Bowl(3)
    //Cupboard構造方法。
    Cupboard
    f1(2)
    // main函式
    Creating new Cupboard() in main
    // 每建立一個物件,就會建立一份非靜態成員變數。
    //所以,會執行Cupboard的第一句 Bowl bowl3 = new Bowl(3);
    Bowl(3)
    Cupboard
    f1(2)
    Creating new Cupboard() in main
    Bowl(3)
    Cupboard
    f1(2)
    f2(1)
    f3(1)

5.7.3 顯示的靜態初始化

靜態塊–這段程式碼只執行一次:當首次生成這個類的一個物件時,或者首次訪問那個類的靜態資料成員時(即便從未生成那個類的物件)。

package Cha5;
import static tools.Print.print;

class Cup{
    Cup(int marker){
        print("Cup("+marker+")");
    }
    void f(int marker){
        print("f("+marker+")");
    }
}

class Cups{
    static Cup cup1;
    static Cup cup2;
    static{
        cup1 = new Cup(1);
        cup2 = new Cup(2);
    }
    Cups(){
        print("Cups()");
    }
}
public class ExplicitStatic {
    public static void main(String[] args) {
        print("Inside main()");
        Cups.cup1.f(99);
    }
}
Output:
    // main函式列印
    Inside main()
    // 呼叫Cups的靜態成員變數cup1,會載入這個類。先初始化靜態變數和執行靜態程式碼塊。
    // 列印Cup(1);
    Cup(1)
    Cup(2)
    f(99)

5.7.4 非靜態例項初始化

package Cha5;
import static tools.Print.print;

class Mug{
    Mug(int marker){
        print("Mug("+marker+")");
    }
    void f(int marker){
        print("f("+marker+")");
    }
}

public class Mugs {
    Mug mug1;
    Mug mug2;
    // 沒有static,每次新建一個Mugs物件,
    // 都會執行一次,因為每個物件都有自己的域。
    {
        mug1 = new Mug(1);
        mug2 = new Mug(2);
        print("mug1 & mug2 initialized");
    }
    Mugs(){
       print("Mugs()");
    }
    Mugs(int i){
        print("Mugs(int)");
    }
    public static void main(String[] args){
        print("Inside main()");
        new Mugs();
        print("new Mugs() completed");
        new Mugs(1);
        print("new Mugs(1) completed");
    }

}
Output:
    Inside main()
    Mug(1)
    Mug(2)
    mug1 & mug2 initialized
    Mugs()
    new Mugs() completed
    Mug(1)
    Mug(2)
    mug1 & mug2 initialized
    Mugs(int)
    new Mugs(1) completed

5.8 陣列初始化

int[] a 和 int a[] 都是合理的。

// 只能用於方法定義處

Integer[] a = {new Integer(1), new Integer(2), 3,};

// 可以用於任何地方

Integer[] a = new Integer[] {new Integer(1), new Integer(2), 3,};

5.9 列舉型別

package Cha5;

enum Spiciness{
NOT,MILD,MEDIUM,HOT,FLAMING
}

public class Burrito {
Spiciness degree;
public Burrito(Spiciness degree){
    this.degree = degree;
}
public void dedcribe(){
System.out.print("This burrito is");
    switch(degree){
        case NOT: System.out.println("not spicy at all");
            break;
        case MILD:
        case MEDIUM:
            System.out.println("a little hot");
            break;
        case HOT:
        case FLAMING:
        default:
            System.out.println("maybe too hot");
    }
}

public static void main(String[] args) {
    Burrito
    plain = new Burrito(Spiciness.NOT);
    Burrito greenChile = new Burrito(Spiciness.MEDIUM);
    Burrito jalapeno = new Burrito(Spiciness.HOT);
    plain.dedcribe();
    greenChile.dedcribe();
    jalapeno.dedcribe();
}

}
This burrito isnot spicy at all
This burrito isa little hot
This burrito ismaybe too hot