読者です 読者をやめる 読者になる 読者になる

ほげほげ(仮)

仮死状態

インナークラスについてまとめてみた

Java


結構なんとなくな状態でやってきたJavaのインナークラス(内部クラス)についてまとめました。

publicなインナークラス

public class Outer {
    private int field;
    private static int staticField;
    public void hoge() {
        // アウタークラスからインスタンスの生成可能
        Inner inner = new Inner();
        inner.bar();
        System.out.println("Outer#hoge");
    }
    public class Inner {
        public void bar() {
            // アウタークラスのフィールド、static変数を参照可能
            int local = field;
            int local2 = staticField;
            System.out.println("Inner#bar");
        }
    }
}

アウタークラスからインスタンスの生成が可能です。
また、逆にアウタークラスのフィールドをインナークラスでも参照可能です。

public class Main {
    public static void main(String[] args) {
        // インナークラスのインスタンスをアウタークラスのインスタンス経由で生成
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();
    }
}

外部からもアウタークラスのインスタンスからインナークラスのインスタンスを生成できます。

privateなインナークラス

public class Outer {
    private int field;
    private static int staticField;
    public void hoge() {
        // アウタークラスからインスタンスの生成可能
        Inner inner = new Inner();
        inner.bar();
        System.out.println("Outer#hoge");
    }
    private class Inner {
        public void bar() {
            // アウタークラスのフィールド、static変数を参照可能
            int local = field;
            int local2 = staticField;
            System.out.println("Inner#bar");
        }
    }
}

インナークラスをprivateにした場合はアウタークラスとの関係はpublicと同じで特に変わりません。

public class Main {
    public static void main(String[] args) {
        Outer outer = new Outer();
        Outer.Inner inner = outer.new Inner();	// コンパイルエラー
    }
}

外部クラスからの場合はコンパイルエラーとなりインスタンスを生成できません。

staticなインナークラス

public class Outer {
    private int field;
    private static int staticField;
    public void hoge() {
        // アウタークラスからインスタンスの生成可能
        Inner inner = new Inner();
        inner.bar();
        System.out.println("Outer#hoge");
    }
    static class Inner {
        public void bar() {
            int local = field;	// コンパイルエラー
            int local2 = staticField;
            System.out.println("Inner#bar");
        }
    }
}

staticな場合はインナークラスからアウタークラスのインスタンス変数にアクセスできません。
static変数にはアクセスできます。

public class Main {
    public static void main(String[] args) {
        // 直接インスタンスを生成
        Outer.Inner inner = new Outer.Inner();
        inner.bar();
    }
}

外部クラスからインスタンスを生成するときはアウタークラスのインスタンスを経由しなくても直接生成できます。
privateなstaticの内部クラスについては外部にも公開されません。



まとめ

簡単にまとめてみましたが、こんな感じになりました。
staticのインナークラスはインナークラスではなく、メンバという扱いになるようです。


使いどころについては外部に公開したくない場合や、インナークラスでアウタークラスのインスタンス変数を使う場合などで変わってくると思います。