Thinking in Java 第四版完整版 第五章練習題 初始化與清理
阿新 • • 發佈:2019-01-09
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;
}
}
}
}