內部類別 x 列舉 x 垃圾回收機制

列舉,類別的一種,可以存在於其他類別內部,只有初始化時可產生物件,不可被繼承,但可以實作介面如下
   1:  package Test_Enum;
   2:   
   3:  public class Test_enum_1 
   4:  {
   5:   
   6:      enum BlankE1{}//沒有物件的列舉
   7:      
   8:      enum SimpleE1{SE1,SE2,SE3}//有三個物件的列舉
   9:      
  10:      enum TestE1 implements if1 //列舉可實作介面
  11:      {
  12:          TE1 //使用預設建構子
  13:          {
  14:              //內部類別實作區
  15:              void enumPrint(){}//因為有列舉的抽象方法,所以必須在每個列舉物件中實作
  16:          }
  17:          ,TE2(2)//使用改寫建構子
  18:          {
  19:              //內部類別實作區
  20:              void enumPrint(){}//因為有列舉的抽象方法,所以必須在每個列舉物件中實作
  21:          }
  22:          ;// ; 之前代表有2個物件
  23:          
  24:          TestE1()//列舉的預設建構式, 忽略 private 修飾
  25:          {
  26:              System.out.println("in TestE1");
  27:          }
  28:          
  29:          TestE1(int i)//建構式2,多載
  30:          {
  31:              System.out.println("in TestE1 2");
  32:          }
  33:          
  34:          public int teNum; //屬性
  35:          
  36:          public void show() //方法
  37:          {
  38:              System.out.println("show");
  39:          }
  40:          
  41:          public int getif1Num()//覆寫 if1 的 getif1Num 方法
  42:          {
  43:              return if1Num;
  44:          }
  45:          
  46:          abstract void enumPrint();//這是在列舉中的抽象方法,必須在每個列舉物件中改寫
  47:          
  48:      }
  49:      
  50:      /**
  51:       * @param args
  52:       */
  53:      public static void main(String[] args) 
  54:      {
  55:          // TODO Auto-generated method stub
  56:   
  57:          TestE1 te2 = TestE1.TE2;//第1種操作
  58:          System.out.println(te2.toString());//TE2
  59:          te2.show();//show
  60:          
  61:          TestE1[] teArr = TestE1.values();//第2種操作
  62:          System.out.println(teArr.length);//2
  63:          
  64:          TestE1 ee1 = TestE1.valueOf("TE1");//第3種操作
  65:          System.out.println(ee1);//TE1
  66:          
  67:          TestE1 eee1 = TestE1.valueOf(TestE1.class, "TE2");//第4種操作
  68:          System.out.println(eee1);//TE2
  69:      }
  70:  }
  71:   
  72:  interface if1
  73:  {
  74:       public final int if1Num =0;
  75:       
  76:       int getif1Num();//抽象方法 省略了 public abstract
  77:  }


內部類別,可分 一般內部類別,函式(方法)內部類別,匿名內部類別,靜態內部類別,如下

   1:  package InnerClass;
   2:   
   3:  public class Inner_Class 
   4:  {
   5:      /**
   6:       * @param args
   7:       */
   8:      public static void main(String[] args) {
   9:          // TODO Auto-generated method stub
  10:          
  11:          //宣告建立方法1
  12:          Outc1 oc1 = new Outc1();//先建立外部類別實體 oc1
  13:          Outc1.Inc1 in1 = oc1.new Inc1();//再藉由 oc1 建立 內部類別實體
  14:          
  15:          //也可以同時宣告建立
  16:          Outc1.Inc1 in2 = new Outc1().new Inc1();
  17:          in1.getincNum();
  18:          
  19:          //呼叫 showoutc1 方法建立方法內部類別
  20:          oc1.showoutc1();
  21:          
  22:          //建立靜態內部類別
  23:          Outc1.Inst1 inst1 = new Outc1.Inst1();//注意new的方法
  24:          inst1.showinstNum1();//因為此方法非靜態所以呼叫要使用實體
  25:          Outc1.Inst1.showOutc1Num();//因為此方法為靜態所以可透過類別名稱呼叫
  26:          
  27:          //匿名內部類別,用來實作 If1 介面
  28:          If1 if1 = new If1()
  29:          {
  30:              public void showi1()//匿名類別的方法,不建議使用 可定義不可使用
  31:              {
  32:                  System.out.println("showi1");
  33:              }
  34:              
  35:              public void showif1Num1()
  36:              {
  37:                  System.out.println("show if1");
  38:              }
  39:          };
  40:          
  41:          if1.showif1Num1();
  42:          //if1.showi1(); 不可使用
  43:          
  44:      }
  45:   
  46:  }
  47:   
  48:  class Outc1
  49:  {
  50:      private int outc1 =10;
  51:      
  52:      static int outc2 = 99;
  53:      
  54:      class Inc1//一般內部類別
  55:      {
  56:          int incNum =0;//一般內部類別的屬性
  57:          public void getincNum()//一般內部類別的方法
  58:          {
  59:              System.out.println(Outc1.this.outc1);//可存取外部類別的屬性
  60:              System.out.println(incNum);
  61:          }
  62:      }
  63:      
  64:      void showoutc1()
  65:      {
  66:          class Inc2//方法內部類別
  67:          {
  68:              int inc2Num = 20;//方法內部類別的屬性
  69:              void showinc2Num()//方法內部類別的方法
  70:              {
  71:                  System.out.println(inc2Num);
  72:              }
  73:          }
  74:          
  75:          Inc2 inc2 = new Inc2();//建立方法內部類別的實體必須在其類別定義之後
  76:          inc2.showinc2Num();//呼叫方法內部類別的方法
  77:      }
  78:      
  79:      static class Inst1//靜態內部類別
  80:      {
  81:          int instNum1 = 0;
  82:          
  83:          void showinstNum1()
  84:          {
  85:              System.out.println(instNum1);
  86:          }
  87:          
  88:          static void showOutc1Num()
  89:          {
  90:              System.out.println(Outc1.outc2);//靜態內部類別只可存取外部類別中 static 成員
  91:              //System.out.println(Outc1.this.outc1);不能存取外部類別非 static 成員
  92:          }
  93:      }
  94:  }
  95:   
  96:  interface If1
  97:  {
  98:      final public int if1Num1 =0;
  99:      
 100:      public abstract void showif1Num1();
 101:  }


垃圾回收,java有自己的垃圾回收機制,由 JVM 控制,只要物件沒有參照到實體,就有可能被回收,使用 null , 或改參照到其他實體都會讓原本的實體被回收, System.gc( ) 建議 JVM 回收無用的實體,確定回收實體前會先呼叫 finalize ( ) 方法
   1:  package Test_GC;
   2:   
   3:  class GCa
   4:  {
   5:      public String name;
   6:      
   7:      public GCa(String name)//建構子
   8:      {
   9:          this.name = name;
  10:      }
  11:      public void finalize()//覆寫 object 的 finalize 方法,在gc前會被呼叫
  12:      {
  13:          System.out.println(name);
  14:      }
  15:      
  16:  }
  17:   
  18:  public class Test_GC {
  19:   
  20:      /**
  21:       * @param args
  22:       */
  23:      public static void main(String[] args) {
  24:          // TODO Auto-generated method stub
  25:          
  26:          GCa a1 = new GCa("a1");
  27:          GCa a2 = new GCa("a2");
  28:          GCa a3 = new GCa("a3");
  29:          
  30:          a1 = null;//使用 null 讓 a1 目前不去參考到任何的物件, 不過之後還是可以指派
物件給 a1
  31:          
  32:          a2 = a3;//把 a3 的實體記憶體位址指派給 a2, 所以a2也會參照到 a3的實體記憶體位址
  33:          
  34:          for(int i =0; i<100; i++){
  35:              System.gc();//a1 a2
  36:          }
  37:          
  38:          
  39:      }
  40:   
  41:  }