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 8 java/lang/Object:getClass ()Ljava/lang/Class;
// 6: pop
// 7: invokespecial 14 com/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 8 java/lang/Object:getClass ()Ljava/lang/Class;
// 6: pop
// 7: invokespecial 14 com/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编程思想一书。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.