ネストクラスのインスタンス化

// 外側のクラス
class OuterClass {
    private int instanceVarO = 100;
    private static int staticVarO = 200;

    // 非staticのネストクラス(インナークラス)
    class InnerClass {
        // OK
        void methodI() {
            System.out.println(instanceVarO);
            System.out.println(staticVarO);
        }

        // ERROR: 非staticのネストクラスはstaticメンバを持てない
        static void staticMethodI() {
            System.out.println(instanceVarO);
            System.out.println(staticVarO);
        }
    }

    // staticなネストクラス
    class StaticNestedClass {
        void methodS() {
            // ERROR: 外側のインスタンス変数にはアクセスできない
            System.out.println(instanceVarO);

            // OK
            System.out.println(staticVarO);
        }

        static void staticMethodS() {
            // ERROR: 外側のインスタンス変数にはアクセスできない
            System.out.println(instanceVarO);

            // OK
            System.out.println(staticVarO);
        }
    }
}

// 外部クラス
public class Main {
    public static void main(String[] args) {
        // 非staticのネストクラスをインスタンス化
        OuterClass.InnerClass i = new OuterClass.new InnerClass();

        // staticなネストクラスをインスタンス化
        OuterClass.StaticNestedClass s = new OuterClass.StaticNestedClass();
    }
}
// 外側のクラス
public class Main {
    // 非staticなネストクラス(インナークラス)
    class InnerClass {
        void methodI() {
            System.out.println("非staticネストクラスのメソッド");
        }
    }

    // staticなネストクラス
    class StaticNestedClass {
        static void staticMethodS() {
            System.out.println("staticネストクラスのstaticメソッド");
        }
    }

    // 外側のクラスのメソッド
    public static void main(String[] args) {

        /* -- 非staticなネストクラスのインスタンス化 -- */

        // OK: staticメンバはインスタンス経由でインスタンスメンバにアクセスできる
        new Main().new InnerClass().methodI()

        // ERROR: staticメンバ(main)はインスタンスメンバ(InnerClass)に直接アクセス不可能
        new InnerClass().methodI();

        /* -- staticなネストクラスのインスタンス化 -- */

        // OK: MainインスタンスのStaticNestedClassメンバのstaticMethodSメンバ
        new Main().StaticNestedClass().staticMethodS();

        // OK: staticメンバ(main)はstaticメンバ(StaticNestedClass)に直接アクセス可能
        new StaticNestedClass().staticMethodS();

        // OK: Mainクラスのstaticメンバとして呼び出し
        Main.StaticNestedClass.staticMethodS();

        // OK: staticメンバ(main)はstaticメンバ(StaticNestedClass)に直接アクセス可能
        StaticNestedClass.staticMethodS();
    }
}

ローカルクラス

ローカルクラスは最初からメソッド内でのみ有効であるため、アクセス修飾子やstaticは指定できない。

class OuterClass {
    private static int staticVar = 1;
    private int instanceVar = 2;

    void outerMethod(final int finalArg, int arg) {
        final int finalVarOM = 5;
        int varOM = 6;

        // ローカルクラス
        class LocalClass {
            void localClassMethod() {
                // OK: 外側のクラスのメンバにアクセス可能
                System.out.print(staticVar);
                System.out.print(instanceVar);

                // OK: 外側のメソッドの引数には、
                //     それがfinal(定数)であればアクセス可能
                System.out.print(finalArg);

                // OK: 外側のクラスのローカル変数(メソッド内変数)には、
                //     それがfinal(定数)であればアクセス可能
                System.out.print(finalVarOM);

                // OK: SE8以降なら、暗黙的にfinalが付与されるため、アクセス可能
                System.out.print(arg);
                System.out.print(varOM);

                // ERROR: 暗黙的にfinalが付与されているため、これらは再代入不可
                arg = 100;
                varOM = 100;
            }
        }

        // ローカルクラスをインスタンス化して、そのメソッドを利用
        new LocalClass().localClassMethod();
    }
}

public class Main {
    public static void main(String[] args) {
        OuterClass o = new OuterClass();

        o.outerMethod(3, 4);
        // RESULT: 12345
    }
}

匿名クラス

interface MyInterface {
    void methodI();
}

class OuterClass {
    void methodO() {
        // 無名の実装クラスをインスタンス化してメソッド呼び出し
        new MyInterface() {
            public void methodI() {
                System.out.println("インターフェースの抽象メソッドを実装しました");
            }
        }.methodI();
    }
}

public class Main {
    public static void main(String[] args) {

        new OuterClass().method();
        // RESULT: インターフェースの抽象メソッドを実装しました
    }
}