Java编程思想 练习题(四)


一、创建一个类,它包含一个未初始化的String引用。验证该引用被Java初始化成了null。

public class Main {
    public static void main(String[] args) {
        Test test = new Test();
        if (test.str == null) {
            System.out.println("String default init is null.");
        }
    }
}
class Test {
    String str;
}

返回:

String default init is null.

二、创建一个类,它包含一个在定义时就被初始化了的String域,以及另一个通过构造器初始化的String域。这两种方式有何差异?

public class Main {
    public static void main(String[] args) {
        Test test = new Test("initing");
        System.out.println("inited:" + test.inited + ", initing:" + test.initing);
    }
}
class Test {
    String inited = "inited";
    String initing;
    public Test(String initing) {
        System.out.println("constructor inited:" + this.inited + ", initing:" + this.initing);
        this.initing = initing;
    }
}

返回:

constructor inited:inited, initing:null
inited:inited, initing:initing

三、创建一个带默认构造器的类,在构造器中打印一条消息。为这个类创建一个对象。

public class Main {                                     
    public static void main(String[] args) {            
        new Test();                                     
    }                                                   
}                                                       
class Test {                                            
    public Test() {                                     
        System.out.println("defaut constructor");       
    }                                                   
}                                                       

返回:

defaut constructor

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

public class Main {                                                       
    public static void main(String[] args) {                              
        new Test("param");                                                
    }                                                                     
}                                                                         
class Test {                                                              
    public Test() {                                                       
        System.out.println("defaut constructor");                         
    }                                                                     
    public Test(String s) {                                               
        System.out.println("has param constructor, param is {" + s + "}");
    }                                                                     
}                                                                         

返回:

has param constructor, param is {param}

五、创建一个名为Dog的类,它具有重载的bark()方法。此方法应根据不同的基本数据类型进行重载,并根据被调用的版本,打印出不同类型的狗吠(barking)、咆哮(howing)等信息。编写mian()来调用所以不同版本的方法。

public class Main {
    public static void main(String[] args) {
        Bark bark = new Bark();
        bark.bark(1);
        bark.bark('c');
    }
}
class Bark {
    public void bark(int i) {
        System.out.println("barking");
    }
    public void bark(char c) {
        System.out.println("howling");
    }
}

返回:

barking
howling

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

public class Main {
    public static void main(String[] args) {
        Bark bark = new Bark();
        bark.bark(1, 'c');
        bark.bark('c', 1);
    }
}
class Bark {
    public void bark(int i, char c) {
        System.out.println("barking");
    }
    public void bark(char c, int i) {
        System.out.println("howling");
    }
}

返回:

barking
howling

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

public class Main {
    public static void main(String[] args) {
        Test test = new Test();
        test.fun();
    }
}
class Test {
    public void fun() {
        System.out.println("auto create default constructor");
    }
}

返回:

auto create default constructor  

八、编写具有两个方法的类,在第一个方法内调用第二个方法两次;第一次调用时,不使用this,第二次调用时,使用this——这里只是为了验证它是起作用的,你不应该在实践中使用这种方法。

public class Main {
    public static void main(String[] args) {
        new Test().test2();
    }
}
class Test {
    public Test test1(String str) {
        System.out.println(str);
        return this;
    }
    public void test2() {
        test1("第一次调用");
        this.test1("第二次调用");
    }
}

返回:

第一次调用
第二次调用

九、编写具有两个构造器(重载)的类,并在第一个构造器中通过this调用第二个构造器。

public class Main {
    public static void main(String[] args) {
        new Test();
    }
}
class Test {
    private String str;
    public Test() {
        this("Test");
    }
    public Test(String str) {
        this.str = str + "1";
        System.out.println(this.str);
    }
}

返回:

Test1

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

public class Main {
    public static void main(String[] args) {
        Test test = new Test();
        new Test();
        System.gc();
    }
}
class Test {
    private static int temp;
    private int id = temp++;
    public Test() {
        System.out.println("constructor id=" + this.id);
    }
    @Override
    public void finalize() {
        try {
            System.out.println("finalize id=" + this.id);
            super.finalize();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}

返回:

constructor id=0
constructor id=1
finalize id=1

  

十一、修改前一个练习的程序,让你的finalize()总会被调用。

public class Main {
    public static void main(String[] args) {
        Test test = new Test();
        new Test();
        test = null; // 失去引用,被回收
        System.gc();
    }
}
class Test {
    private static int temp;
    private int id = temp++;
    public Test() {
        System.out.println("constructor id=" + this.id);
    }
    @Override
    public void finalize() {
        try {
            System.out.println("finalize id=" + this.id);
            super.finalize();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}

返回:

constructor id=0
constructor id=1
finalize id=1
finalize id=0

  

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

public class Main {
    public static void main(String[] args) {
        Tank tank = new Tank();
        tank.empty();
        new Tank().empty();
        new Tank();
        tank = null;
        System.gc();
    }
}
class Tank {
    private static int temp;
    private int id = temp++;
    boolean empty;

    public Tank() {
        this.empty = false;
        System.out.println("Tank id=" + this.id);
    }

    public void empty() {
        this.empty = true;
        System.out.println("Tank id=" + this.id + ", empty=true");
    }
    @Override
    protected void finalize() {
        if (empty) {
            System.out.println("Tank id=" + this.id + " empty=true finalized");
        } else {
            System.out.println("Tank id=" + this.id + " empty=false can't finalize");
        }
    }
}

返回:

Tank id=0
Tank id=0, empty=true
Tank id=1
Tank id=1, empty=true
Tank id=2
Tank id=2 empty=false can't finalize
Tank id=1 empty=true finalized
Tank id=0 empty=true finalized

十三、验证前面段落中的语句。

public class Main {
    public static void main(String[] args) {
        System.out.println("Inside main()");
        // 无论是运行(1)代码访问静态的cup1对象,
        // 还是把(1)注释掉,运行(2)的代码,
        // Cups的静态初始化动作都会得到执行。
        Cups.cup1.f(99); // (1)
    }
//    static Cups cups1 = new Cups(); //(2)
//    static Cups cups2 = new Cups(); //(2)
}
class Cup {
    Cup(int marker) {
        System.out.println("Cup (" + marker + ")");
    }
    void f(int marker) {
        System.out.println("f (" + marker + ")");
    }
}
class Cups {
    static Cup cup1;
    static Cup cup2;
    static {
        cup1 = new Cup(1);
        cup2 = new Cup(2);
    }
    Cups() {
        System.out.println("Cups()");
    }
}

返回:

Inside main()
Cup (1)
Cup (2)
f (99)

注释掉(1),运行(2),返回:

Cup (1)
Cup (2)
Cups()
Cups()
Inside main()

十四、编写一个类,拥有两个静态字符串域,其中一个在定义处初始化,另一个在静态块中初始化。现在,加入一个静态方法用以打印出两个字段值。请证明它们都会在被使用之前完成初始化动作。

public class Main {
    public static void main(String[] args) {
        System.out.println("Inside main()");
        Cups.cup1.fun();
    }
}
class Cup {
    private int i;
    Cup(int i) {
        this.i = i;
        System.out.println("Cup (" + i + ")");
    }
    void fun() {
        System.out.println("fun (" + i + ")");
    }
}
class Cups {
    static Cup cup1;
    static Cup cup2 = new Cup(2);
    static {
        cup1 = new Cup(1);
    }
}

返回:

Inside main()
Cup (2)
Cup (1)
fun (1)

十五、编写一个含有字符串域的类,并采用实例初始化方式进行初始化。

public class Main {
    StringField stringField1;
    StringField stringField2;
    {
        stringField1 = new StringField("two");
        stringField2 = new StringField();
        System.out.println("stringField1 & stringField1 initialized");
    }
    Main() {
        System.out.println("Main()");
    }
    public static void main(String[] args) {
        System.out.println("Inside main()");
        new Main();
    }
}
class StringField {
    private String str1 = new String("one");
    private String str2;
    StringField() {
        System.out.println("StringField() [ str1=" + str1 + " ]");
        if (str2 != null) {
            System.out.println("StringField() [ str2=" + str2 + " ]");
        }
    }
    StringField(String str) {
        this.str2 = str;
        System.out.println("StringField(String) [ str2=" + str2 + " ]");
    }
}

返回:

Inside main()
StringField(String) [ str2=two ]
StringField() [ str1=one ]
stringField1 & stringField1 initialized
Main()

十六、创建一个String对象数据,并为每一个元素都赋值一个String。用for循环来打印该数组。

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        String[] strArr = new String[3];
        for (int i = 0; i < strArr.length; i++) {
            strArr[i] = String.valueOf(i);
        }
        System.out.println(Arrays.toString(strArr));
    }
}

返回:

[0, 1, 2]

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

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        StringField[] strArr = new StringField[1];
        System.out.println(Arrays.toString(strArr));
    }
}
class StringField {
    StringField(String str) {
        System.out.println("StringField [ " + str + " ]");
    }
}

返回:

[null]

十八、通过创建对象赋值给引用数组,从而完成前一个练习。

import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        StringField[] strArr = new StringField[]{new StringField("str0"),new StringField("str1"),};
        System.out.println(Arrays.toString(strArr));
    }
}
class StringField {
    StringField(String str) {
        System.out.println("StringField [ " + str + " ]");
    }
}

返回:

StringField [ str0 ]
StringField [ str1 ]
[StringField@61a485d2, StringField@39fb3ab6]

十九、写一个类,它接受一个可变参数的String数组。验证你可以向该方法传递一个用逗号分隔的String列表,或是一个String[]。

public class Main {
    public static void main(String[] args) {
        new Test().fun("H", "e", "l", "l", "o", ",");
        new Test().fun("W", "o", "r", "l", "d", "!");
    }
}
class Test {
    public void fun(String... strArr) {
        for (String str : strArr) {
            System.out.print(str);
        }
        System.out.println();
    }
}

返回:

Hello,
World!

  

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

public class Main {
    public static void main(String... args) {
        for(String param:args){
            System.out.print(param + " ");
        }
    }
}

在idea中做启动配置

返回:

Hello World ! 

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

public enum RMBEnum {
    ONE, TWO, FIVE, TEN, FIVTY, HUNDRED
}
public class Main {
    public static void main(String... args) {
        for (RMBEnum rmb : RMBEnum.values()) {
            System.out.println("No." + rmb.ordinal() + " is " + rmb + ".");
        }
    }
}

返回:

No.0 is ONE.
No.1 is TWO.
No.2 is FIVE.
No.3 is TEN.
No.4 is FIVTY.
No.5 is HUNDRED.

二十二、在前面的例子中,为enum写一个switch语句,对于每一个case,输出该特定货币的描述。

public class Main {
    public static void main(String... args) {
        for (RMBEnum rmb : RMBEnum.values()) {
            fun(rmb);
        }
    }
    private static void fun(RMBEnum rmb){
        switch (rmb) {
            case ONE:
                System.out.println("RMB face value " + rmb + " is smallest.");
                break;
            case TWO:
                System.out.println("RMB face value " + rmb + " is small");
                break;
            case FIVE:
                System.out.println("RMB face value " + rmb + " is middle.");
                break;
            case TEN:
                System.out.println("RMB face value " + rmb + " is large.");
                break;
            case FIVTY:
                System.out.println("RMB face value " + rmb + " is extra large.");
                break;
            case HUNDRED:
                System.out.println(rmb + " is largest.");
                break;
        }
    }
}

返回:

RMB face value ONE is smallest.
RMB face value TWO is small
RMB face value FIVE is middle.
RMB face value TEN is large.
RMB face value FIVTY is extra large.
RMB face value HUNDRED is largest.
优质内容筛选与推荐>>
1、c++容器使用经验总结
2、SQL SERVER 常用字符串函数
3、Sumlime text3 安装包、汉化包、注册码
4、Graph Cuts初步理解
5、程序员的八荣八耻


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn