靜態與非靜態巢狀類

在建立巢狀類時,你可以選擇將巢狀類設定為 static:

public class OuterClass1 {

    private static class StaticNestedClass {

    }

}

或非靜態:

public class OuterClass2 {

    private class NestedClass {

    }

}

從本質上講,靜態巢狀類沒有 ***** 外部類的周圍*例項,而非靜態巢狀類則具有。這會影響允許例項化巢狀類的位置和時間,以及允許這些巢狀類的哪些例項訪問。新增到上面的示例:

public class OuterClass1 {

    private int aField;
    public void aMethod(){}

    private static class StaticNestedClass {
        private int innerField;

        private StaticNestedClass() {
             innerField = aField; //Illegal, can't access aField from static context 
             aMethod();           //Illegal, can't call aMethod from static context 
        }

        private StaticNestedClass(OuterClass1 instance) {
             innerField = instance.aField; //Legal
        }

    }

    public static void aStaticMethod() {
        StaticNestedClass s = new StaticNestedClass(); //Legal, able to construct in static context
        //Do stuff involving s...
    }

}

public class OuterClass2 {

    private int aField;

    public void aMethod() {}

    private class NestedClass {
        private int innerField;

        private NestedClass() {
             innerField = aField; //Legal   
             aMethod(); //Legal
        }
    }

    public void aNonStaticMethod() {
        NestedClass s = new NestedClass(); //Legal
    }

    public static void aStaticMethod() {
        NestedClass s = new NestedClass(); //Illegal. Can't construct without surrounding OuterClass2 instance.
                                         //As this is a static context, there is no surrounding OuterClass2 instance
    }
}

因此,你對靜態與非靜態的決定主要取決於你是否需要能夠直接訪問外部類的欄位和方法,儘管它也會影響你何時何地構造巢狀類。

根據經驗,除非你需要訪問外部類的欄位和方法,否則請將巢狀類設定為靜態。與將欄位設為私有類似,除非你需要公開,這會降低巢狀類可用的可見性(通過不允許訪問外部例項),從而降低出錯的可能性。