トップ 一覧 ping 検索 ヘルプ RSS ログイン

SJC-P インナークラスの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!!!SJC-P クラス、インタフェース、列挙型を宣言
!!インナークラス
!「通常」のインナークラス 
以下のようなクラスではない 
+静的ネストクラス 
+メソッドローカルなインナークラス 
+無名インナークラス 

*「通常」のインナークラスは、static宣言を持つことはできない(1)
*Outer クラスのメンバーを参照できる(2)
*Outer クラスの参照は クラス名.this で参照できる(3)
*Outer クラスのコード内からは、インナークラスを直接インスタンス化できる(4)
*Outer クラスのコード外から、インナークラスをインスタンス化するには、アウタークラスの参照が必要(5)

 package innerclass;
 
 /**
  * 「通常」のインナークラス
  *   以下のようなクラスではない
  *   ・静的ネストクラス
  *   ・メソッドローカルなインナークラス
  *   ・無名インナークラス
  * @author Yagi Hiroto
  */
 public class InnerClassTest1 {
     private String outerName = "InnerClassTest1";
 
     /**
      * 「通常」のインナークラス
      */
     class InnerClass {
         // (1) 「通常」のインナークラスは、static宣言を持つことはできない
         public /* static */ void printName() {
             System.out.println("my name : InnerClass");
             // (2) Outer クラスのメンバーを参照できる
             System.out.println("outer name : " + outerName);
             // (3) Outer クラスの参照は クラス名.this で参照できる
             System.out.println("outer  : " + InnerClassTest1.this);
         }
     }
     
     /*
      * Outer クラスのコード「内」から、インナークラスのインスタンスを生成する
      */ 
     public void printInnerName() {
         // (4) インナークラスを直接インスタンス化できる
         InnerClass ic = new InnerClass();
         ic.printName();
     }
     
     public static void main(String[] args) {
         InnerClassTest1 me = new InnerClassTest1();
         me.printInnerName();
         
         InnerClassTest2 ic2 = new InnerClassTest2();
         ic2.printOtherInnerName();
     }
 }
 class InnerClassTest2 {
     /*
      * Outer クラスのコード「外」から、インナークラスのインスタンスを生成する
      */ 
     public void printOtherInnerName() {
         // (5) インナークラスのインスタンス化には、アウタークラスの参照が必要
         InnerClassTest1.InnerClass ic
             = new InnerClassTest1().new InnerClass();
         ic.printName();
     }
 }
!メソッドローカルなインナークラス
*Outerクラスのメンバにアクセス可能(1)
*ローカル変数にはアクセスできない(2)
**インナークラスはヒープに置かれるため、メソッドから抜けるとスタックにアクセスできなくなる
*final なローカル変数にはアクセスできる(3)
*メソッドを抜けても生存している(4)

 package innerclass;
 
 public class InnerClassTest3 {
     private int memberInt = 123;
     private Object obj;
     public void testMethodLocalInnerClass() {
         int       localInt = 456;
         final int finalInt = 789;
         
         class MethodInner {
             void printInt() {
                 // (1) Outerクラスのメンバにアクセス可能
                 System.out.println("Member :" + memberInt);
                 // (2) ローカル変数にはアクセスできない
                 //     インナークラスはヒープに置かれるため、メソッドから抜けるとスタックにアクセスできなくなる
              // System.out.println("Local  :" + localInt);
                 // (3) final なローカル変数にはアクセスできる
                 System.out.println("Final  :" + finalInt);
             }
             public String toString() {
                 return "MethodInner";
             }
         }
         
         MethodInner mi = new MethodInner();
         mi.printInt();
         obj = mi;
     }
     
     public static void main(String[] args) {
         InnerClassTest3 me = new InnerClassTest3();
         me.testMethodLocalInnerClass();
         // (4) メソッドを抜けても生存している
         System.out.println(me.obj.toString());
     }
 }
!無名インナークラス
*無名インナークラスとしてサブクラス化(1)
*スーパークラスのメソッドをオーバーライド(2)
*末尾はセミコロン(3)

 package innerclass;
 
 public class InnerClassTest4 {
 
     public void testAnonymousInner() {
         /*
          * 無名インナークラス
          *  (1) 無名インナークラスとしてサブクラス化
          */
         BaseClass bc = new BaseClass() {
             // (2) スーパークラスのメソッドをオーバーライド
             public String getName() {
                 return "AnonymousDerivClass";
             }
         }; // (3) 末尾はセミコロン
         
         System.out.println(bc.getName());
     }
     
     public static void main(String[] args) {
         (new InnerClassTest4()).testAnonymousInner();
     }
 }
 class BaseClass {
     public String getName() {
         return "BaseClass";
     }
 }
!無名インナークラス(インターフェース実装クラス)
*無名インナークラスとしてインターフェースを実装(1)
*インターフェースのメソッドを実装(2)
*末尾はセミコロン(3)

 package innerclass;
 
 public class InnerClassTest5 {
     
     public void testAnonymousInner() {
         /*
          * 無名インナークラス
          *  (1) 無名インナークラスとしてインターフェースを実装
          */
         InfBase ib = new InfBase() {
             // (2) インターフェースのメソッドを実装
             public String getName() {
                 return "AnonymousDerivClass";
             }
         }; // (3) 末尾はセミコロン
         
         System.out.println(ib.getName());
     }
     public static void main(String[] args) {
         (new InnerClassTest5()).testAnonymousInner();
     }
 }
 interface InfBase {
     String getName();
 }
!無名インナークラス(メソッド引数として使用)
*セミコロン不要(1)
*}); で終わる(2)

 package innerclass;
 
 public class InnerClassTest6 {
     public void testParamAnonymousClass(InfBase2 base) {
         System.out.println(base.getName());
     }
     public static void main(String[] args) {
         InnerClassTest6 me = new InnerClassTest6();
         
         me.testParamAnonymousClass(
                 /* メソッド引数として無名インナークラスを利用する */
                 new InfBase2() {
                     public String getName() {
                         return "Parameter AnonymousClass";
                     }
                 } // (1)セミコロン不要
         );  // (2) }); で終わる
     }
 }
 interface InfBase2 {
     String getName();
 }