| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

SJC-P インナークラス

提供: MyMemoWiki
ナビゲーションに移動 検索に移動

SJC-P クラス、インタフェース、列挙型を宣言

インナークラス

「通常」のインナークラス

以下のようなクラスではない

  1. 静的ネストクラス
  2. メソッドローカルなインナークラス
  3. 無名インナークラス
  • 「通常」のインナークラスは、static宣言を持つことはできない(1)
  • Outer クラスのメンバーを参照できる(2)
  • Outer クラスの参照は クラス名.this で参照できる(3)
  • Outer クラスのコード内からは、インナークラスを直接インスタンス化できる(4)
  • Outer クラスのコード外から、インナークラスをインスタンス化するには、アウタークラスの参照が必要(5)
  1. package innerclass;
  2.  
  3. /**
  4. * 「通常」のインナークラス
  5. * 以下のようなクラスではない
  6. * ・静的ネストクラス
  7. * ・メソッドローカルなインナークラス
  8. * ・無名インナークラス
  9. * @author Yagi Hiroto
  10. */
  11. public class InnerClassTest1 {
  12. private String outerName = "InnerClassTest1";
  13.  
  14. /**
  15. * 「通常」のインナークラス
  16. */
  17. class InnerClass {
  18. // (1) 「通常」のインナークラスは、static宣言を持つことはできない
  19. public /* static */ void printName() {
  20. System.out.println("my name : InnerClass");
  21. // (2) Outer クラスのメンバーを参照できる
  22. System.out.println("outer name : " + outerName);
  23. // (3) Outer クラスの参照は クラス名.this で参照できる
  24. System.out.println("outer : " + InnerClassTest1.this);
  25. }
  26. }
  27. /*
  28. * Outer クラスのコード「内」から、インナークラスのインスタンスを生成する
  29. */
  30. public void printInnerName() {
  31. // (4) インナークラスを直接インスタンス化できる
  32. InnerClass ic = new InnerClass();
  33. ic.printName();
  34. }
  35. public static void main(String[] args) {
  36. InnerClassTest1 me = new InnerClassTest1();
  37. me.printInnerName();
  38. InnerClassTest2 ic2 = new InnerClassTest2();
  39. ic2.printOtherInnerName();
  40. }
  41. }
  42. class InnerClassTest2 {
  43. /*
  44. * Outer クラスのコード「外」から、インナークラスのインスタンスを生成する
  45. */
  46. public void printOtherInnerName() {
  47. // (5) インナークラスのインスタンス化には、アウタークラスの参照が必要
  48. InnerClassTest1.InnerClass ic
  49. = new InnerClassTest1().new InnerClass();
  50. ic.printName();
  51. }
  52. }

メソッドローカルなインナークラス

  • Outerクラスのメンバにアクセス可能(1)
  • ローカル変数にはアクセスできない(2)
    • インナークラスはヒープに置かれるため、メソッドから抜けるとスタックにアクセスできなくなる
  • final なローカル変数にはアクセスできる(3)
  • メソッドを抜けても生存している(4)
  1. package innerclass;
  2.  
  3. public class InnerClassTest3 {
  4. private int memberInt = 123;
  5. private Object obj;
  6. public void testMethodLocalInnerClass() {
  7. int localInt = 456;
  8. final int finalInt = 789;
  9. class MethodInner {
  10. void printInt() {
  11. // (1) Outerクラスのメンバにアクセス可能
  12. System.out.println("Member :" + memberInt);
  13. // (2) ローカル変数にはアクセスできない
  14. // インナークラスはヒープに置かれるため、メソッドから抜けるとスタックにアクセスできなくなる
  15. // System.out.println("Local :" + localInt);
  16. // (3) final なローカル変数にはアクセスできる
  17. System.out.println("Final :" + finalInt);
  18. }
  19. public String toString() {
  20. return "MethodInner";
  21. }
  22. }
  23. MethodInner mi = new MethodInner();
  24. mi.printInt();
  25. obj = mi;
  26. }
  27. public static void main(String[] args) {
  28. InnerClassTest3 me = new InnerClassTest3();
  29. me.testMethodLocalInnerClass();
  30. // (4) メソッドを抜けても生存している
  31. System.out.println(me.obj.toString());
  32. }
  33. }

無名インナークラス

  • 無名インナークラスとしてサブクラス化(1)
  • スーパークラスのメソッドをオーバーライド(2)
  • 末尾はセミコロン(3)
  1. package innerclass;
  2.  
  3. public class InnerClassTest4 {
  4.  
  5. public void testAnonymousInner() {
  6. /*
  7. * 無名インナークラス
  8. * (1) 無名インナークラスとしてサブクラス化
  9. */
  10. BaseClass bc = new BaseClass() {
  11. // (2) スーパークラスのメソッドをオーバーライド
  12. public String getName() {
  13. return "AnonymousDerivClass";
  14. }
  15. }; // (3) 末尾はセミコロン
  16. System.out.println(bc.getName());
  17. }
  18. public static void main(String[] args) {
  19. (new InnerClassTest4()).testAnonymousInner();
  20. }
  21. }
  22. class BaseClass {
  23. public String getName() {
  24. return "BaseClass";
  25. }
  26. }

無名インナークラス(インターフェース実装クラス)

  • 無名インナークラスとしてインターフェースを実装(1)
  • インターフェースのメソッドを実装(2)
  • 末尾はセミコロン(3)
  1. package innerclass;
  2.  
  3. public class InnerClassTest5 {
  4. public void testAnonymousInner() {
  5. /*
  6. * 無名インナークラス
  7. * (1) 無名インナークラスとしてインターフェースを実装
  8. */
  9. InfBase ib = new InfBase() {
  10. // (2) インターフェースのメソッドを実装
  11. public String getName() {
  12. return "AnonymousDerivClass";
  13. }
  14. }; // (3) 末尾はセミコロン
  15. System.out.println(ib.getName());
  16. }
  17. public static void main(String[] args) {
  18. (new InnerClassTest5()).testAnonymousInner();
  19. }
  20. }
  21. interface InfBase {
  22. String getName();
  23. }

無名インナークラス(メソッド引数として使用)

  • セミコロン不要(1)
  • }); で終わる(2)
  1. package innerclass;
  2.  
  3. public class InnerClassTest6 {
  4. public void testParamAnonymousClass(InfBase2 base) {
  5. System.out.println(base.getName());
  6. }
  7. public static void main(String[] args) {
  8. InnerClassTest6 me = new InnerClassTest6();
  9. me.testParamAnonymousClass(
  10. /* メソッド引数として無名インナークラスを利用する */
  11. new InfBase2() {
  12. public String getName() {
  13. return "Parameter AnonymousClass";
  14. }
  15. } // (1)セミコロン不要
  16. ); // (2) }); で終わる
  17. }
  18. }
  19. interface InfBase2 {
  20. String getName();
  21. }