1. 程式人生 > >Thinking in Java 第四版完整版 第五章練習題 初始化與清理

Thinking in Java 第四版完整版 第五章練習題 初始化與清理

Thinking in Java 第四版完整版 第五章練習題,記錄一下(jdk1.8.0)

1.

/**
 * 練習1:建立一個類,它包含一個未初始化的String引用。驗證該引用被Java初始化成了null。
 * @author admin11
 * @date 2018年3月2日
 */

public class Exercise501 {

    String str;
    public static void main(String[] args) {
        System.out.println(new Exercise501().str);
    }
}

這裡寫圖片描述

2.

/**
 * 練習2:建立一個類,它包含一個在定義時就被初始化了的String域,以及另一個通過構造器
 * 初始化的String域。這兩種方式有何差異?
 * @author admin11
 * @date 2018年3月2日
 */
public class Exercise502 {

    String str1 = "str1";
    String str2;
    public Exercise502(String str) {
        this.str2 = str;
    }

    // str1欄位在建構函式之前被初始化;從技術上講,str2欄位也是如此,在建立物件時設定成null。
// str2欄位可以選擇在呼叫建構函式時設定值。 public static void main(String[] args) { Exercise502 e = new Exercise502("str"); System.out.println("str1 = " + e.str1); System.out.println("str2 = " + e.str2); } }

這裡寫圖片描述

3.

/**
 * 練習3:建立一個帶預設構造器(即無參構造器)的類,在構造器中列印一條訊息。
 * 為這個類建立一個物件。
 * @author
admin11 * @date 2018年3月5日 */
public class Exercise503 { public Exercise503() { System.out.println("Default Construct"); } public static void main(String[] args) { new Exercise503(); } }

這裡寫圖片描述

4.

/**
 * 練習4:為前一個練習中的類新增一個過載構造器,令其接收一個字串引數,
 * 並在構造器中把你自己的訊息和接收的引數一起打印出來。
 * @author admin11
 * @date 2018年3月5日
 */
public class Exercise504 {

    public Exercise504() {
        System.out.println("Exercise504()");
    }

    public Exercise504(String str) {
        System.out.println("Exercise504(Strting str): " + str);
    }

    public static void main(String[] args) {
        new Exercise504();
        new Exercise504("hello");
    }
}

這裡寫圖片描述

5.

/**
 * 練習5:建立一個名為Dog的類,它具有過載的bark()方法。此方法應根據不同的基本資料
 * 進行過載,並根據被呼叫的版本,打印出不同型別的狗吠(barking)、咆哮(howling)
 * 等資訊。編寫main()來呼叫所有不同版本的方法。
 * @author admin11
 * @date 2018年3月5日
 */

class Dog {
    public void bark() {
        System.out.println("barking");
    }

    public void bark(String str) {
        System.out.println("howling: " + str);
    }

    public void bark(int i) {
        System.out.println("howling: " + i);
    }
}

public class Exercise505 {

    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.bark();
        dog.bark("barking...");
        dog.bark(2);
    }
}

這裡寫圖片描述

6.

/**
 * 練習6:修改前一個練習的程式,讓兩個過載方法各自接收兩個型別的不同的引數,
 * 但二者順序相反。驗證其是否工作。
 * @author admin11
 * @date 2018年3月5日
 */

class Dog2 {
    public void bark(int i, String str) {
        System.out.println("int i = " + i + ", String str = " + str);
    }

    public void bark(String str, int i) {
        System.out.println("String str = " + str + ", int i = " + i);
    }
}

public class Exercise506 {

    public static void main(String[] args) {
        Dog2 dog = new Dog2();
        dog.bark(6, "barking");
        dog.bark("howling", 7);
    }
}

這裡寫圖片描述

7.

/**
 * 練習7:建立一個沒有構造器的類,並在main()中建立其物件,用以
 * 驗證編譯器是否真的自動加入了預設構造器。
 * @author admin11
 * @date 2018年3月5日
 */
public class Exercise507 {

    public static void main(String[] args) {
        Exercise507 e = new Exercise507();
        System.out.println(e);
    }
}

這裡寫圖片描述

8.

/**
 * 練習8:編寫具有兩個方法的類,在第一個方法內呼叫第二個方法兩次:
 * 第一次呼叫時不使用this關鍵字,第二次呼叫時使用this關鍵字---
 * 這裡只是為了驗證它是起作用的,你不應該在實踐中使用這種方式。
 * @author admin11
 * @date 2018年3月9日
 */
public class Exercise508 {

    public void method1() {
        method2();
        this.method2();
    }

    public void method2() {
        System.out.println("method2");
    }

    public static void main(String[] args) {
        Exercise508 e = new Exercise508();
        e.method1();
    }
}

這裡寫圖片描述

9.

/**
 * 練習9:編寫具有兩個(過載)構造器的類,並在第一個構造器
 * 中通過this呼叫第二個構造器。
 * @author admin11
 * @date 2018年3月9日
 */
public class Exercise509 {

    public Exercise509(String s,int i) {
        this(i);
        System.out.println(s);
    }

    public Exercise509(int i) {
        System.out.println(i);
    }

    public static void main(String[] args) {
        new Exercise509(27);
        new Exercise509("hello", 56);
    }
}

這裡寫圖片描述

10.

/**
 * 練習10:編寫具有finalize()方法的類,並在方法中列印訊息。
 * 在main()中為該類建立一個物件。試解釋這個程式的行為。
 * @author admin11
 * @date 2018年3月9日
 */
public class Exercise510 {

    @Override
    protected void finalize() throws Throwable {
        System.out.println("finalize() called");
    }

    public static void main(String[] args) {
        new Exercise510(); // 可能不會看到被呼叫的終結器,因為程式通常不會為收集器生成足夠的垃圾來執行
    }
}

這裡寫圖片描述

11.

/**
 * 練習11:修改前一個練習的程式,讓你的finalize()總會被呼叫。
 * @author admin11
 * @date 2018年3月12日
 */
public class Exercise511 {

    @Override
    protected void finalize() {
        System.out.println("finalize() called");
    }

    public static void main(String[] args) {
        new Exercise511();
        System.gc();
        System.runFinalization();
    }
}

這裡寫圖片描述

12.

/**
 * 練習12:編寫名為Tank的類,此類的狀態可以是“滿的”或“空的”。
 * 其終結條件是:物件被清理時必須處於空狀態。請編寫finalize()
 * 以檢驗終結條件是否成立。在main()中測試Tank可能發生的幾種使用方式。
 * @author admin11
 * @date 2018年3月12日
 */

class Tank {
    static int counter;
    int id = counter++;
    boolean full;
    public Tank() {
        System.out.println("Tank " + id + " created");
        full = true;
    }

    public void empty() {
        full = false;
    }

    @Override
    protected void finalize()  {
        if(full) {
            System.out.println("Error: tank " + id + " must be empty at cleanup");
        } else {
            System.out.println("Tank " + id + " cleaned up OK");
        }
    }

    @Override
    public String toString() {
        return "Tank " + id;
    }
}

public class Exercise512 {

    public static void main(String[] args) {
        new Tank().empty();
        new Tank();
        System.gc();
        System.runFinalization();
    }
}

這裡寫圖片描述

13.

/**
 * 練習13:驗證前面段落中的語句。
 * @author admin11
 * @date 2018年3月12日
 */
public class Exercise513 {

    public static void main(String[] args) {
        System.out.println("Exercise left to reader");
    }
}

這裡寫圖片描述

14.

/**
 * 練習14:編寫一個類,擁有兩個靜態字串域,其中一個在定義處初始化,
 * 另一個在靜態塊中初始化。現在,加入一個靜態方法用以打印出兩個欄位值。
 * 請證明它們都會在被使用之前完成初始化動作。
 * @author admin11
 * @date 2018年3月12日
 */
public class Exercise514 {

    static String s1 = "Initialized at definition";
    static String s2;
    static {
        s2 = "Initialized in satic block";
    }

    public static void main(String[] args) {
        System.out.println("s1 = " + s1);
        System.out.println("s2 = " + s2);
    }
}

這裡寫圖片描述

15.

/**
 * 練習15:編寫一個含有字串域的類,並採用例項初始化方式進行初始化。
 * @author admin11
 * @date 2018年3月12日
 */
public class Exercise515 {

    String str;
    {
        str = " instance initialization";
    }
    public Exercise515() {
        System.out.println("Default constructor: " + str);
    }

    public Exercise515(String str) {
        this.str = str;
        System.out.println("constructor: " + str);
    }

    public static void main(String[] args) {
        new Exercise515();
        new Exercise515("exercise");
    }
}

這裡寫圖片描述

16.

/**
 * 練習16:建立一個String物件陣列,併為每一個元素都賦值一個String。
 * 用for迴圈來列印該陣列。
 * @author admin11
 * @date 2018年3月12日
 */
public class Exercise516 {

    public static void main(String[] args) {
        String str[] = new String[3];
        str[0] = "hello";
        str[1] = "hi";
        str[2] = "exercise";

        for (int i = 0; i < str.length; i++) {
            System.out.println(str[i]);
        }

        String sa2[] = {
                "These", "are", "some", "strings"
                };
        for (int i = 0; i < sa2.length; i++) {
            System.out.println(sa2[i]);
        }
    }
}

這裡寫圖片描述

17.

/**
 * 練習17:建立一個類,它有一個接受一個String引數的構造器。在構造階段,
 * 列印該引數。建立一個該類的物件引用陣列,但是不實際去建立物件賦值給該陣列。
 * 當執行程式時,請注意來自對該構造器的呼叫中的初始化訊息是否列印了出來。
 * @author admin11
 * @date 2018年3月13日
 */
class Test {
    public Test(String s) {
        System.out.println("String constructor; s = " + s);
    }
}

public class Exercise517 {
    Test[] arr1 = new Test[5];
    public static void main(String[] args) {
        Test[] arr2 = new Test[5];
    }
}

這裡寫圖片描述

18.

/**
 * 練習18:通過建立物件賦值給引用陣列,從而完成前一個練習。
 * @author admin11
 * @date 2018年3月13日
 */
class Test2 {
    public Test2(String s) {
        System.out.println("String constructor; s = " + s);
    }
}

public class Exercise518 {

    static Test2[] arr1 = new Test2[5];
    public static void main(String[] args) {
        Test2[] arr2 = new Test2[5];
        for (int i = 0; i < arr2.length; i++) {
            //arr1[i] = new Test2("arr1" + i);
            arr2[i] = new Test2("arr2" + i);
        }
    }
}

這裡寫圖片描述

19.

/**
 * 練習19:寫一個類,它接收一個可變引數的String陣列。
 * 驗證你可以向該方法傳遞一個用逗號分隔的String列表,或是一個String[]。
 * @author admin11
 * @date 2018年3月13日
 */
public class Exercise519 {

    static void printStrings(String... str) {
        for (String string : str) {
            System.out.println(string);
        }
    }

    public static void main(String[] args) {
        printStrings("there", "are", "some", "Strings");
        printStrings(new String[]{"there", "are", "some", "Strings"});
    }
}

這裡寫圖片描述

20.

/**
 * 練習20:建立一個使用可變引數列表而不是普通的main()語法的main()。
 * 列印所產生的args陣列的所有元素,並用各種不同數量的命令列引數來測試它。
 * @author admin11
 * @date 2018年3月14日
 */
public class Exercise520 {

    public static void main(String... args) {
        for (String string : args) {
            System.out.println(string);
        }
    }
}

這裡寫圖片描述

21.

/**
 * 練習21:建立一個enum,它包含紙幣中最小面值的6種類型。
 * 通過values()迴圈並列印每一個值及其ordinal()。
 * @author admin11
 * @date 2018年3月15日
 */

enum PaperCurrencyTypes {
    ONE, TWO, FIVE, TEN, TWENTY, FIFTY
}

public class Exercise521 {

    public static void main(String[] args) {
        for (PaperCurrencyTypes s : PaperCurrencyTypes.values()) {
            System.out.println(s + ", ordinal " + s.ordinal());
        }
    }
}

這裡寫圖片描述

22.

/**
 * 練習22:在前面的例子中,為enum寫一個switch語句,
 * 對於每一個case,輸出該特定貨幣的描述。
 * @author admin11
 * @date 2018年3月15日
 */

enum PaperCurrencyType {
    ONE, TWO, FIVE, TEN, TWENTY, FIFTY
}

public class Exercise522 {

    public static void main(String[] args) {
        for (PaperCurrencyType s : PaperCurrencyType.values()) {
            switch (s) {
            case ONE:
                System.out.println("ONE");
                break;
            case TWO:
                System.out.println("TWO");
                break;
            case FIVE:
                System.out.println("FIVE");
                break;
            case TEN:
                System.out.println("TEN");
                break;
            case TWENTY:
                System.out.println("TWENTY");
                break;
            case FIFTY:
                System.out.println("FIFTY");
                break;
            default:
                System.out.println("defalut");
                break;
            }
        }
    }
}

這裡寫圖片描述