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