Java 內部類實現說明
阿新 • • 發佈:2018-12-26
先看程式碼例子:
//TestInnerClass.java
import com.lin.liu.OuterClass.InnerClass;
class OuterClass{
class InnerClass{
}
}
public class TestInnerClass extends InnerClass{
public TestInnerClass(OuterClass oc) {
oc.super();
}
public static void main(String[] args) {
TestInnerClass tClass = new TestInnerClass(new OuterClass());
System.out.println(tClass.hashCode());
}
}
在這段程式碼中TestInnerClass 繼承自InnerClass,仔細觀察可以發現,在TestInnerClass的建構函式中就必須有OuterClass的引用。
我們對上面這段程式碼進行編譯可以得到三個class檔案,分別是OuterClass$InnerClass.class、OuterClass.class、TestInnerClass.class
然後進行反編譯,就可以看到編譯器是如何對內部類進行處理的。
//OuterClass.class
class OuterClass
{
class InnerClass
{
InnerClass()
{
}
}
}
沒什麼要說明的。
//OuterClass$InnerClass.class
class OuterClass$InnerClass
{
final OuterClass this$0;
OuterClass$InnerClass(OuterClass paramOuterClass)
{
this.this$0 = paramOuterClass;
}
}
這就是內部類的真是實現了,可以看到,編譯器自動添加了一個外部類的final引用,並且建構函式的第一個引數位置新增一個OuterClass的引用作為引數(也可以寫一個複雜一點的類進行觀察,此處只為說明)。
//TestInnerClass.class
public class TestInnerClass extends OuterClass.InnerClass
{
public TestInnerClass(OuterClass oc)
{
// Byte code:
// 0: aload_0
// 1: aload_1
// 2: dup
// 3: invokevirtual 8java/lang/Object:getClass()Ljava/lang/Class;
// 6: pop
// 7: invokespecial 14com/lin/liu/OuterClass$InnerClass:<init>(Lcom/lin/liu/OuterClass;)V
// 10: return
}
public static void main(String[] args)
{
TestInnerClass tClass = new TestInnerClass(new OuterClass());
System.out.println(tClass.hashCode());
}
}
//關於oc.super()的說明
他的實現可以理解為this.super(oc),而普通的super()呼叫相當於this.super(this)。
所以在使用的時候只要保證InnerClass中的final OuterClass this$0;能得到正確初始化就可以保證執行時的正確性。
具體使用技巧可以參看java程式設計思想一書。
//TestInnerClass.java
import com.lin.liu.OuterClass.InnerClass;
class OuterClass{
class InnerClass{
}
}
public class TestInnerClass extends InnerClass{
public TestInnerClass(OuterClass oc) {
oc.super();
}
public static void main(String[] args) {
TestInnerClass tClass = new TestInnerClass(new OuterClass());
System.out.println(tClass.hashCode());
}
}
在這段程式碼中TestInnerClass 繼承自InnerClass,仔細觀察可以發現,在TestInnerClass的建構函式中就必須有OuterClass的引用。
我們對上面這段程式碼進行編譯可以得到三個class檔案,分別是OuterClass$InnerClass.class、OuterClass.class、TestInnerClass.class
然後進行反編譯,就可以看到編譯器是如何對內部類進行處理的。
//OuterClass.class
class OuterClass
{
class InnerClass
{
InnerClass()
{
}
}
}
沒什麼要說明的。
//OuterClass$InnerClass.class
class OuterClass$InnerClass
{
final OuterClass this$0;
OuterClass$InnerClass(OuterClass paramOuterClass)
{
this.this$0 = paramOuterClass;
}
}
這就是內部類的真是實現了,可以看到,編譯器自動添加了一個外部類的final引用,並且建構函式的第一個引數位置新增一個OuterClass的引用作為引數(也可以寫一個複雜一點的類進行觀察,此處只為說明)。
//TestInnerClass.class
public class TestInnerClass extends OuterClass.InnerClass
{
public TestInnerClass(OuterClass oc)
{
// Byte code:
// 0: aload_0
// 1: aload_1
// 2: dup
// 3: invokevirtual 8java/lang/Object:getClass()Ljava/lang/Class;
// 6: pop
// 7: invokespecial 14com/lin/liu/OuterClass$InnerClass:<init>(Lcom/lin/liu/OuterClass;)V
// 10: return
}
public static void main(String[] args)
{
TestInnerClass tClass = new TestInnerClass(new OuterClass());
System.out.println(tClass.hashCode());
}
}
//關於oc.super()的說明
他的實現可以理解為this.super(oc),而普通的super()呼叫相當於this.super(this)。
所以在使用的時候只要保證InnerClass中的final OuterClass this$0;能得到正確初始化就可以保證執行時的正確性。
具體使用技巧可以參看java程式設計思想一書。