內部類和靜態嵌套類

術語規範:按照官方文檔,定義在外部類(封裝類)內部的類稱之爲nested class,根據是否被static關鍵字修飾又分爲兩類:static nested classes 和 inner classes。閉包

class OuterClass {

    static class StaticNestedClass {}
    class InnerClass {}
}

使用嵌套類的好處在於:this

  • 當某個類爲旁類專用時,將其寫成嵌套類能使得代碼結構更緊湊。指針

  • 嵌套類增長了封裝性code

內部類和靜態嵌套類的不一樣根源來自於static,最大區別在於訪問外部類成員的權限。對象

1.靜態嵌套類

static修飾符使得嵌套類對象成爲外部類的靜態成員,與外部類直接關聯。作用域

這樣靜態嵌套類做爲一個靜態成員,僅能訪問外部類的靜態成員,由於外部類中的非靜態成員與外部類對象相關,靜態嵌套類就不能訪問他們,這使得靜態嵌套類的功能變的很弱,可用之處不多。文檔

另外由於靜態嵌套類是依附於外部類而非外部類對象的,因此不一樣的外部類對象共享一個靜態嵌套類,這一點與內部類不一樣,能夠用來包裝main方法。class

靜態嵌套類的聲明示例:變量

OuterClass.StaticNestedClass nestedObject =
     new OuterClass.StaticNestedClass();

2.內部類

沒有static修飾意味着一個內部類是和外部類對象關聯的,也能夠說一個內部類對象存在於外部類對象中,是外部類對象的一個成員,所以內部類對象能夠訪問外部類對象的所有成員,包括私有成員。原理

  • 由於內部類依賴於外部類對象而存在,因此不能定義任何靜態成員。

  • 內部類對象能夠訪問外部類的全部成員變量,包括私有成員,這是Java閉包的原理;

  • 由於內部類隱含對外部類的引用,因此外部類就不能被JVM的垃圾回收機制自動垃圾回收。

  • 不一樣的外部類對象之間沒有公共的內部類對象成員。

內部類的聲明示例:

OuterClass.InnerClass innerObject = new OuterObject().new InnerClass();

3.變量遮蔽Shadowing

嵌套類和封裝類以及局部方法區的變量做用域有重疊,若是有同名變量將發生變量遮蔽。

public class ShadowTest {

    public int x = 0;

    class FirstLevel {

        public int x = 1;

        void methodInFirstLevel(int x) {
            System.out.println("x = " + x);
            System.out.println("this.x = " + this.x);
            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
        }
    }

    public static void main(String... args) {
        ShadowTest st = new ShadowTest();
        ShadowTest.FirstLevel fl = st.new FirstLevel();
        fl.methodInFirstLevel(23);
    }
}

注意這裏對3種不一樣變量的引用方式,結果以下

x = 23                  //1.  局部變量
this.x = 1              //2.內部類變量
ShadowTest.this.x = 0   //3.外部類變量

內部類中this指針指向內部類本身,ShadowTest.this則指向外部類對象;

不加修飾的變量,將執行就近匹配原則;若是名稱相同將發生變量遮蔽效應;爲了防止隱患,內部類引用外部類對象時應使用第三種方法。

相關文章
相關標籤/搜索