java编程思想第4版 第五章习题

练习1:创建一个类,包含一个未初始化的String引用。验证该引用被java初始化成为了null。

  代码:

public class TestNewClassWithNULL {

    String a;

    public static void main(String[] args) {
        TestNewClassWithNULL newClassWithNULL = new TestNewClassWithNULL();
        System.out.println(newClassWithNULL.a);
    }
}

输出:

null

练习2:创建一个类,他包含一个在定义时就被初始化的String域,以及另一个通过构造器初始化的String域,这两种方式有何差异?

代码

public class TestNewClassWithTwoString {
    String a = "a";
    String b;
    public TestNewClassWithTwoString(){
        System.out.println(a);
        System.out.println(b);
        b = "b";
    }

    public static void main(String[] args) {
        TestNewClassWithTwoString testNewClassWithTwoString = new TestNewClassWithTwoString();
        System.out.println(testNewClassWithTwoString.a);
        System.out.println(testNewClassWithTwoString.b);
    }
}

输出:

a
null
a
b
 

区别:在创建类对象时,定义时被初始化的对象已经被创建(指向常量,不为空),构造器初始化需要首先指向新创建的常量才能被初始化。

练习3:创建一个带默认构造器(无参构造器)的类,在构造器中打印一条消息。为该类创建一个对象

代码:

public class TestConstructor {

    public TestConstructor(){
        System.out.println("non param");
    }

    public static void main(String[] args) {
        TestConstructor testConstructor = new TestConstructor();
    }
}

输出:

non param
 

练习4:为前一个练习中的类添加一个重载构造器,令其接受一个字符串参数,并在构造器中把你自己的消息和接受的参数信息一起打印出来。

代码:

public class TestConstructor {

    public TestConstructor(){
        System.out.println("non param");
    }

    public TestConstructor(String param){
        System.out.println("receive param:" + param);
    }
    public static void main(String[] args) {
        TestConstructor testConstructor = new TestConstructor();
        TestConstructor testConstructor1 = new TestConstructor("hahaha");
    }
}

输出:

non param
receive param:hahaha

练习5:创建一个名为Dog的类,他具有重载的bark()方法。此方法根据不同的基本数据类型进行重载,并根据被调用的版本,打印出不同类型的狗吠(barking),咆哮(howling)等信息。编写main()来调用所有不同版本的方法。

代码:

public class Dog {

    public Dog(boolean bark) {
        System.out.println("bark?" + bark);
    }

    public Dog(byte bark) {
        System.out.println("byte bark wee");
    }

    public Dog(char bark) {
        System.out.println("char bark quietly");
    }

    public Dog(short bark) {
        System.out.println("short bark within earshot");
    }

    public Dog(int bark) {
        System.out.println("int bark normally");
    }

    public Dog(long bark) {
        System.out.println("long bark excitingly");
    }

    public Dog(float bark) {
        System.out.println("float bark loudly");
    }

    public Dog(double bark) {
        System.out.println("double bark deafening");
    }

    public static void main(String[] args) {
        new Dog(false);
        new Dog((byte) 1);
        new Dog('a');
        new Dog((short) 1);
        new Dog(1);
        new Dog((long) 1);
        new Dog((float) 1);
        new Dog((double) 1);
    }
}

输出:

bark?false
byte bark wee
char bark quietly
short bark within earshot
int bark normally
long bark excitingly
float bark loudly
double bark deafening

练习6:修改前一个练习的程序,让两个重载方法各自接受两个类型的不同的参数,但两者顺序相反,验证其是否工作。

代码:

public class Dog {

    public Dog(boolean bark) {
        System.out.println("bark?" + bark);
    }

    public Dog(byte bark) {
        System.out.println("byte bark wee");
    }

    public Dog(char bark, int times) {
        System.out.println("char bark quietly" + times);
    }

    public Dog(short bark) {
        System.out.println("short bark within earshot");
    }

    public Dog(int bark, char times) {
        System.out.println("int bark normally" + times);
    }

    public Dog(long bark) {
        System.out.println("long bark excitingly");
    }

    public Dog(float bark) {
        System.out.println("float bark loudly");
    }

    public Dog(double bark) {
        System.out.println("double bark deafening");
    }

    public static void main(String[] args) {
        new Dog(false);
        new Dog((byte) 1);
        new Dog('a', 66);
        new Dog((short) 1);
        new Dog(1, '6');
        new Dog((long) 1);
        new Dog((float) 1);
        new Dog((double) 1);
    }
}

输出:

bark?false
byte bark wee
char bark quietly66
short bark within earshot
int bark normally6
long bark excitingly
float bark loudly
double bark deafening
 

练习7:创建一个没有构造器的类,并在main()中创建其对象,用以验证编译器是否真的自动加入的默认构造器。

答:显然

练习8:略

练习9:this构造器

代码:

public class TestConstructor {

    public TestConstructor(){
        this(11);
    }

    public TestConstructor(int a){
        System.out.println(a);
    }

    public static void main(String[] args) {
        TestConstructor testConstructor = new TestConstructor();
    }
}

输出:

11

练习10:编写具有finalize()方法的类,并在方法中打印消息。在main()中为该类创建一鞥对象。试图解释这个程序的行为。

代码

public class HumanResource {

    /**
     * 被优化了
     */
    @Override
    protected void finalize() {
        System.out.println("optimized");
    }

    public static void main(String[] args) {
        HumanResource humanResource = new HumanResource();
    }
}

练习11:修改前一个练习的程序,让你的finalize()总是被调用

代码:

public class HumanResource {

    public int age;

    public HumanResource(int age) {
        this.age = age;
    }

    /**
     * 被优化了
     */
    @Override
    protected void finalize() {
        System.out.println("optimized");
    }

    public static void main(String[] args) {
        HumanResource humanResource = new HumanResource(40);
//        if (humanResource.age > 35) {
            //引用置空时很有必要的,否则不会被优化掉
            humanResource = null;
//        }
        System.gc();
        System.out.println("finish");
    }
}

输出:

finish
optimized

代表没有用了就被优化掉了。

练习12:编写名为Tank的类,此类的状态可以是“满的”或“空的”,其终结条件是对象被清理的时必须处于空状态。请编写finalize()以检验终结条件是否成立。在main()中测试Tank可能发生的几种使用方式。

代码

public class Tank {

    boolean isFull = false;

    public Tank(boolean isFull) {
        this.isFull = isFull;
    }

    @Override
    protected void finalize() {
        if (!isFull) {
            System.out.println("is empty");
        }
    }

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

输出:

is empty

练习13:验证静态代码块

代码:

public class TestStaticBlock {
    public static class Cup {
        public Cup(int maker) {
            System.out.println("Cup(" + maker + ")");
        }

        void f(int maker) {
            System.out.println("f(" + maker + ")");
        }
    }

    public static class Cups{
        static Cup cup1;
        static Cup cup2;
        static {
            cup1 = new Cup(1);
            cup2 = new Cup(2);
        }
        Cups(){
            System.out.println("cups");
        }
    }

    public static void main(String[] args) {
        Cups.cup1.f(99);
    }

    static Cups cups = new Cups();
}

输出:

Cup(1)
Cup(2)
cups
f(99)

练习14:编写一个类,拥有两个静态字符串域,其中一个在定义处初始化,另一个在静态块中初始化。现在,加入一个静态方法用以打印出两个字段值。证明他们都在使用前完成了初始化动作。

代码

public class TestStaticBlock {
    public static class Cup {
        public Cup(int maker) {
            System.out.println("Cup(" + maker + ")");
        }

        void f(int maker) {
            System.out.println("f(" + maker + ")");
        }
    }

    public static class Cups{
        static Cup cup1;
        static Cup cup2 = new Cup(2);
        static {
            cup1 = new Cup(1);
        }
        Cups(){
            System.out.println("cups");
        }
    }

    public static void main(String[] args) {
        Cups.cup1.f(99);
    }

    static Cups cups = new Cups();
}

输出

Cup(2)
Cup(1)
cups
f(99)

练习15:编写一个含有字符串域的类,并采用实例化初始化的方式进行初始化。

代码:

public class TestStaticBlock {
    public static class Cup {
        public Cup() {
            System.out.println("no maker");
        }

        public Cup(int maker) {
            System.out.println("Cup(" + maker + ")");
        }

    }

    public static class Cups {
        Cup cup1;
        Cup cup2 = new Cup(2);

        {
            cup1 = new Cup(1);
            System.out.println("complete cup 2");
        }

        Cups() {
            System.out.println("cups");
        }

        Cups(int i){
            System.out.println("cups : " + i);
        }
    }

    public static void main(String[] args) {
        System.out.println("start main");
        new Cups();
        System.out.println("cups complete");
        new Cups(1);
        System.out.println("cups 1 complete");
    }

}

输出:

start main
Cup(2)
Cup(1)
complete cup 2
cups
cups complete
Cup(2)
Cup(1)
complete cup 2
cups : 1
cups 1 complete

练习16:创建一个String对象数组,并为每一个元素都赋值一个String。用for循环来打印该数组。

代码:

public class TestStringArray {
    String[] strings = new String[]{"1", "2", "aaa", "bao"};

    public static void main(String[] args) {
        TestStringArray testStringArray = new TestStringArray();
        for (String str : testStringArray.strings) {
            System.out.println(str);
        }
    }
}

输出:

1
2
aaa
bao

练习17:创建一个类,他有一个接受一个String参数的构造器。在构造阶段,打印该参数。创建一个该类的对象引用数组,但是不实际去创建对象赋值给给该数组。当运行程序时,请注意来自对该构造器的调用中的初始化消息是否打印了出来。

练习18:赋值给引用对象。

代码

import java.util.Arrays;

public class TestStringArray {
    String[] strings;

    public TestStringArray(String[] strings) {
        System.out.println(Arrays.toString(strings));
        this.strings = strings;
    }

    public static void main(String[] args) {
        TestStringArray testStringArray = new TestStringArray(new String[1]);
        //未初始化str[0],会空指针
//        for (String str : testStringArray.strings) {
//            System.out.println(str);
//        }
    }
}

输出

[null]

练习19:写一个类,接受一个可变的参数的String数组,验证你可以向该方法传递一个逗号分隔的String列表或者一个String[]。

代码:

import com.sun.istack.internal.Nullable;

import java.util.Arrays;

public class TestStringArray {

    public TestStringArray(String... strings) {
        if (strings.length == 0) {
            System.out.println("non param");
            return;
        }
        for (String str : strings) {
            System.out.println(str);
        }
    }

    public static void main(String[] args) {
        new TestStringArray();
        new TestStringArray("a");
        new TestStringArray("a", "bbb");
        new TestStringArray(new String[]{"ccc", "ddd", "fff"});
    }
}

输出:

non param
a
a
bbb
ccc
ddd
fff

练习20:创建一个使用可变参数列表的而不是普通的main()语法的main()。打印所产生的args数组的所有元素,并用各种不同数量的命令行参数来测试他。

代码

public class TestStringArray {


    public static void main(String... args) {
        if(args.length == 0){
            System.out.println("non param");
        }
        for(String str:args){
            System.out.println(str);
        }
    }
}
配置

 输出

test1

test2

练习21:创建一个enum,它包含纸币中最小面值的6种类型。通过values()循环并打印每一个值及其ordinal()。

练习22:在前面的例子种,为enum写一个switch语句,对于每一个case,输出该特定的货币描述

代码

public class TestEnum {
    public static enum RMB{
        ONE,FIVE,TEN,TWENTY,FIFTY,HUNDRED
    }

    public static void main(String[] args) {
        for (RMB rmb:RMB.values()){
            System.out.println(rmb.ordinal());
            switch (rmb){
                case ONE:
                    System.out.println("一元");
                    break;
                case FIVE:
                    System.out.println("五元");
                    break;
                case TEN:
                    System.out.println("十元");
                    break;
                case TWENTY:
                    System.out.println("二十元");
                    break;
                case FIFTY:
                    System.out.println("五十元");
                    break;
                case HUNDRED:
                    System.out.println("一百元");
                    break;
            }
        }
    }
}

输出

0
一元
1
五元
2
十元
3
二十元
4
五十元
5
一百元
 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值