java 內部類和靜態內部類的區別和使用方法

      在Java代碼的實現過程中,我們經常會使用內部類,內部類的使用也是非常多的,現在羅列一下當前的內部類的知識。

下面說一說內部類(Inner Class)和靜態內部類(Static Nested Class)的區別:
1) 非靜態內部類有一個很大的優點:可以自由使用外部類的所有變量和方法 。
2) 靜態內部類的作用:只是爲了降低包的深度,方便類的使用,靜態內部類適用於包含類當中,但又不依賴與外在的類,不用使用外在類的非靜態屬性和方法,只是爲了方便管理類結構而定義。在創建靜態內部類的時候,不需要外部類對象的引用。

根據Oracle官方的說法:
Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.
從字面上看,一個被稱爲靜態嵌套類,一個被稱爲內部類。
從字面的角度解釋是這樣的:
什麼是嵌套?嵌套就是我跟你沒關係,自己可以完全獨立存在,但是我就想借你的殼用一下,來隱藏一下我自己。
因此,靜態內部類的設計天生就是爲建造者模式的設計開了一道門。

(1)創建實例
   OutClass.InnerClass obj = outClassInstance.new InnerClass(); //注意是外部類實例.new,內部類
   AAA.StaticInner in = new AAA.StaticInner();//注意是外部類本身,靜態內部類

(2)內部類中的this
    內部類中的this與其他類一樣是指的本身。創建內部類對象時,它會與創造它的外圍對象有了某種聯繫,於是能訪問外圍類的所有成員,不需任何特殊條件,可理 解爲內部類鏈接到外部類。 用外部類創建內部類對象時,此內部類對象會祕密的捕獲一個指向外部類的引用,於是,可以通過這個引用來訪問外圍類的成員。

(3)靜態內部類
    關鍵字static中提到Static可以修飾成員變量、方法、代碼塊,其他它還可以修飾內部類,使用static修飾的內部類我們稱之爲靜態內部類,不過我們更喜歡稱之爲嵌套內部類。靜態內部類與非靜態內部類之間存在一個最大的區別,我們知道非靜態內部類在編譯完成之後會隱含地保存着一個引用,該引用是指向創建它的外圍內,但是靜態內部類卻沒有。沒有這個引用就意味着:
1、 它的創建是不需要依賴於外圍類的。
2、 它不能使用任何外圍類的非static成員變量和方法。

實現的代碼如下:

public class OutClassType {

private int age;
private int year;

public static void test(){
System.out.println("OutClassType data.");
}

public class InnerNormalClass{
private int a = 1;
private int b = 2;

public InnerNormalClass(){
System.out.println("init the inner class");
// 普通內部類可以通過this關鍵字無限訪問外部類的成員變量
System.out.println("direct read OutClassType age:"+OutClassType.this.age);

test();
}

public int getA(){
System.out.println("print A.");
return a;
}

public int getB(){
System.out.println("print B.");
return b;
}
}


public static class InnnerStaticClass{
private int c = 15;
private int d = 16;
public int getC(){
System.out.println("print C.");
return c;
}

public int getD(){
return d;
}

public static void testStaticMethod(){
System.out.println("this is static inner class method.");
}
}

public void printInnnerStaticClassData(InnnerStaticClass innnerStaticClass){
System.out.println("print c:"+innnerStaticClass.c+",print d:"+innnerStaticClass.d);
}

public void printInnerNonStaticClassData(InnerNormalClass normalClass){
System.out.println("print a:"+normalClass.a+",print b:"+normalClass.b);
}



public int getAge() {
return age;
}


public void setAge(int age) {
this.age = age;
}


public int getYear() {
return year;
}


public void setYear(int year) {
this.year = year;
}
}

測試代碼如下所示:

private static void testInnerClass(){
OutClassType outClassType = new OutClassType();
// 非靜態的內部類的初始化只能使用outClassType.new的方式生成
OutClassType.InnerNormalClass innerNormalClass = outClassType.new InnerNormalClass();
// 使用內部類的對象訪問內部類成員變量
System.out.println("print the inner method:"+innerNormalClass.getA());

// 靜態內部類的初始化和和非靜態內部類的初始化不一樣,因爲不管是靜態變量還是靜態內部類都是外部類直接所有
OutClassType.InnnerStaticClass innnerStaticClass = new OutClassType.InnnerStaticClass();
System.out.println("print the static class non static method:"+innnerStaticClass.getC());
// 直接調用靜態內部類的靜態方法
OutClassType.InnnerStaticClass.testStaticMethod();

// 外部類的方法中也可以訪問靜態內部類的私有屬性
outClassType.printInnnerStaticClassData(innnerStaticClass);

// 外部類的方法中也可以訪問非靜態內部類的私有屬性
outClassType.printInnerNonStaticClassData(innerNormalClass);

}

測試結果如下所示:

init the inner class
direct read OutClassType age:0
OutClassType data.
print A.
print the inner method:1
print C.
print the static class non static method:15
this is static inner class method.
print c:15,print d:16
print a:1,print b:2


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章