1. 程式人生 > >java編程思想第四版第五章習題

java編程思想第四版第五章習題

調用構造 每次 override 變參 對象賦值 turn AC 初始化 @override

  1. 創建一個類, 它包含一個未初始化的String引用。驗證該引用被Java初始化成了null
    package net.mindview.initialization;
    
    public class Test1 {
        public String str;
        public static void main(String[] args) {
            Test1 t = new Test1();
            System.out.println(t.str);
        }
    
    }

    返回結果

    null

  2. 創建一個類, 它包含一個在定義時就被初始化了的String域, 以及另一個通過構造器初始化的String域, 這兩種方式有何差異?
    package net.mindview.initialization;
    
    
    public class Test2 { public String str1 = "abc"; public String str2; public Test2(){ System.out.println(str1); System.out.println(str2); this.str2 = "def"; System.out.println(str1); System.out.println(str2); } public static void main(String[] args) { Test2 t
    = new Test2(); } }

    運行結果:

    abc
    null
    abc
    def

    結論: 定義是就被初始化的str1只被賦值一次, 而定義時未被初始化str2被賦值了兩次, 第一次是null,第二次是構造器賦值.

  3. 創建一個帶默認構造器的類, 在構造器中打印一條消息. 為這個類創建一個對象.
    package net.mindview.initialization;
    
    public class Test3 {
        public Test3(){
            System.out.println("默認構造器");
        }
        public static void
    main(String[] args) { Test3 t = new Test3(); } }

  4. 為前一個聯系中的類添加一個沖在構造器,令其接受一個字符串參數,並在構造器中吧自己的消息和接受的參數一起打印出來.
    package net.mindview.initialization;
    
    public class Test3 {
        public Test3(){
            System.out.println("默認構造器");
        }
        
        public Test3(String str){
            System.out.println("有一個參數的構造器");
            System.out.println(str);
        }
        
        public static void main(String[] args) {
            Test3 t = new Test3();
            Test3 t2 = new Test3("hello");
        }
    }

  5. 創建一個名為dog的類, 它具有重載的bark()方法, 此方法根據不同的基本數據類型重載, 並根據被調用的版本,打印出不同類型的狗吠(barking),咆哮(howling)等信息.編寫main()來調用所有不同版本的方法
    package net.mindview.initialization;
    
    public class Dog {
        public void bark(){
            System.out.println("barking");
        }
        public void bark(String paoxiao){
            System.out.println("howling");
        }
        public static void main(String[] args) {
            Dog dog1 = new Dog();
            dog1.bark();
            dog1.bark("paoxiao");
        }
    
    }

  6. (略)
  7. (略)
  8. 編寫具有兩個方法的類,在第一個方法內調用第二個方法兩次:第一次調用時不使用this關鍵字,第二次調用時使用this關鍵字-- * 這裏只是為了驗證它是起作用的,你不應該在實踐中使用這種方法。

    package net.mindview.initialization;
    
    public class Test8 {
        public void method1(){
            System.out.println("1");
            method2().method2();
        }
        public Test8 method2(){
            System.out.println("2");
            return this;
        }
        public static void main(String[] args) {
            Test8 t = new Test8();
            t.method1();
        }
    }

  9. (略)
  10. 編寫具有finalize()方法的類,並在方法中打印消息,在main()中為該類創建一個對象,試解釋這個程序的行為。

    package net.mindview.initialization;
    
    public class Test10 {
        @Override
        protected void finalize() throws Throwable {
            System.out.println("調用了finalize方法");
            super.finalize();
        }
        public static void main(String[] args) {
            Test10 t = new Test10();
            t = null;
            System.gc();
            
            Test10 t1 = new Test10();
            t1 = null;
            System.gc();
        }
    
    }

    即便我手動調用垃圾回收處理了, 但finalize方法也不是每次都會被調用. 也就是說雖然我手動觸發垃圾回收, 但實際上, 並沒有真的觸發垃圾回收. 下面這篇文章就解釋原因:http://blog.csdn.net/yewei02538/article/details/52386642

  11. 修改前一個練習的程序,讓你的finalize()總會被調用。

    • 如何才能讓finzlize()總會被調用呢? 手動調用system.runFinalization()
      package net.mindview.initialization;
      
      public class Test10 {
          @Override
          protected void finalize() throws Throwable {
              System.out.println("調用了finalize方法");
              super.finalize();
          }
          public static void main(String[] args) {
              Test10 t = new Test10();
              t = null;
              System.gc();
              
              Test10 t1 = new Test10();
              t1 = null;
              System.gc();
              System.runFinalization();
          }
      
      }

  12. (4)編寫名為Tank的類,此類的狀態可以是“滿的”或“空的”。其終結條件是:對象被清理時必須處於空狀態。 * 請編寫finalize()以檢驗終結條件是否成立,在main()中測試Tank可能發生的幾種使用方式

    package net.mindview.initialization;
    
    public class Tank {
        public String state = "empty";
        
        public Tank(String state){
            this.state = state;
        }
        
        void clear(){
            this.state = "empty";
        }
        
        @Override
        protected void finalize() throws Throwable {
            System.out.println("------finalize---------");
            if(!state.equals("empty")){
                System.out.println("Error!!Tank未被清空");
            }
            super.finalize();
        }
        
        public static void main(String[] args) {
            Tank tank1 = new Tank("full");
            tank1.clear();
            System.gc();
            System.runFinalization();
            
            Tank tank2 = new Tank("full");
            tank1 = null;
            tank2 = null;
            System.gc();
            System.runFinalization();
        }
    
    }

    這裏需要將tank1和tank2手動置為空. 否則垃圾回收機制會將其標記, 然後再下一個周期清除.

  13. (略)
  14. 編寫一個類,擁有兩個靜態字符串域,其中一個在定義處初始化,另一個在靜態塊中初始化。現在,加入一個靜態方法用以打印出兩個字段值。請證明它們都會在被使用之前完成初始化動作。

    package net.mindview.initialization;
    
    public class Test14 {
        public static String str1 = "abc";
        public static String str2;
        static {
            str2 = "def";
        }
        
        public static void print(){
            System.out.println("str1 :"+ str1);
            System.out.println("str2 :"+ str2);
        }
        public static void main(String[] args) {
            print();    
        }
    }

  15. 編寫一個含有字符串域的類,並采用實例初始化方式進行初始化。

    package net.mindview.initialization;
    
    public class Test14 {
        public static String str1 = "abc";
        public static String str2;
        public String str3;
        
        //靜態成員初始化
        static {
            str2 = "def";
            //str3 = "aaa"; //報錯
        }
        
        //非靜態成員初始化
        {
            str3 = "aaa";
            str2 = "mmm";//也可以給靜態成員初始化
        }
        public static void print(){
            System.out.println("str1 :"+ str1);
            System.out.println("str2 :"+ str2);
        }
        public static void main(String[] args) {
            Test14 t = new Test14();
            print();    
            System.out.println("str3 :"+ t.str3);
        }
    }

  16. (略)
  17. 創建一個類,他有一個接受一個String參數的構造器。在構造階段,打印該參數。創建一個該類的對象引用數組,但是不實際去創建對象賦值給該數組。當運行程序時,請註意來自對該構造器的調用中的初始化消息是否打印了出來

    package net.mindview.initialization;
    
    public class Test17 {
        public Test17(String str){
            System.out.println(str);
        }
        public static void main(String[] args) {
            Test17[] tt = null;
        }
    }

    只有實例化的時候才會調用構造方法

  18. 通過創建對象賦值給引用數組,從而完成前一個練習。

    package net.mindview.initialization;
    
    import java.util.Random;
    
    public class Test17 {
        public Test17(String str){
            System.out.println(str);
        }
        public static void main(String[] args) {
            Random rand = new Random();
            Test17[] tt = new Test17[rand.nextInt(100)];
            for(int i=0;i<tt.length; i++){
                tt[i] = new Test17(""+i);
            }
        }
    }

  19. 寫一個類,他接受一個可變參數的String數組,驗證你可以向該方法傳遞一個用逗號分隔的String列表,或是一個String[]。

    package net.mindview.initialization;
    
    public class Test19 {
        public void print(String ...strings){
            for(String str: strings){
                System.out.print(str);
            }
            System.out.println();
        }
        
        public static void main(String[] args) {
            Test19 t = new Test19();
            t.print("aaa", "bbb", "ccc");
            t.print(new String[]{"d","e","f"});
        }
    }

  20. 創建一個使用可變參數列表而不是普通的main()語法的main()。打印所產生的args數組的所有元素,並用各種不同數量的命令行參數來測試它。

    package net.mindview.initialization;
    
    public class Test19 {
            public static void main(String ...args){
            for(String arg: args){
                System.out.println(arg);
            }
        }
    }

  21. 創建一個enum,它包含紙幣中最小面值的6種類型。通過values()循環並打印每一個值及其ordinal()

    package net.mindview.initialization;
    
    enum Money{
        ONE,
        TWO,
        FIVE,
        TEN,
        FIVTY,
        HUNDRED
    }
    public class Test21 {
        
        public static void main(String[] args) {
            for(Money m : Money.values()){
                System.out.println(m + " " + m.ordinal());
            }
    
        }
    
    }

  22. 在前面的例子中,為enum寫一個switch語句,對於每一個case,輸出該特定貨幣的描述。

    package net.mindview.initialization;
    
    enum Money{
        ONE,
        TWO,
        FIVE,
        TEN,
        FIFTY,
        HUNDRED
    }
    public class Test22 {
        Money value;
        public Test22(Money value){
            this.value = value;
        }
        
        public void printValue(){
            switch(value){
                case ONE:
                    System.out.println("1元面值");
                    break;
                case TWO:
                    System.out.println("2元面值");
                    break;
                case FIVE:
                    System.out.println("5元面值");
                    break;
                case TEN:
                    System.out.println("10元面值");
                    break;
                case FIFTY:
                    System.out.println("50元面值");
                    break;
                case HUNDRED:
                    System.out.println("100元面值");
                    break;
            }
        }
        
        
        public static void main(String[] args) {
            Test22 t = new Test22(Money.ONE);
            Test22 t2 = new Test22(Money.TWO);
            Test22 t3 = new Test22(Money.HUNDRED);
            t.printValue();
            t2.printValue();
            t3.printValue();
            
    
        }
    
    }

java編程思想第四版第五章習題