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;
            }
        }
    }
}

这里写图片描述

猜你喜欢

转载自blog.csdn.net/summerSunStart/article/details/79644596