通过class文件可以清楚的知道,这些内部类的构造方法中会自动传入外部类的实例,所以能够访问外部类中的实例。
源码
package com.jwslh.clz;
public class Out {
interface IOut {
void i();
}
void testOut() {
}
class Inner {
public void testInner() {
IOut out = new IOut() {
@Override
public void i() {
testOut();
}
};
}
}
public static void main(String[] args) {
Out out = new Out();
}
}
Out$Inner.class
Compiled from "Out.java"
class com.jwslh.clz.Out$Inner {
final com.jwslh.clz.Out this$0;
// 构造方法中会自动传入外部类的实例,所以创建内部类需要在实例中创建
com.jwslh.clz.Out$Inner(com.jwslh.clz.Out); // 构造方法传入外部类实例
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:Lcom/jwslh/clz/Out; 赋值
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V 调用super
9: return
public void testInner();
Code:
0: new #3 // class com/jwslh/clz/Out$Inner$1
3: dup
4: aload_0
5: invokespecial #4 // Method com/jwslh/clz/Out$Inner$1."<init>":(Lcom/jwslh/clz/Out$Inner;)V
8: astore_1
9: return
}
Out$Inner1.class
Compiled from "Out.java"
class com.jwslh.clz.Out$Inner$1 implements com.jwslh.clz.Out$IOut {
final com.jwslh.clz.Out$Inner this$1;
com.jwslh.clz.Out$Inner$1(com.jwslh.clz.Out$Inner);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$1:Lcom/jwslh/clz/Out$Inner;
5: aload_0
6: invokespecial #2 // Method java/lang/Object."<init>":()V
9: return
public void i();
Code:
0: aload_0
1: getfield #1 // Field this$1:Lcom/jwslh/clz/Out$Inner;
4: getfield #3 // Field com/jwslh/clz/Out$Inner.this$0:Lcom/jwslh/clz/Out;
7: invokevirtual #4 // Method com/jwslh/clz/Out.testOut:()V
10: return
}
Out.class
Compiled from "Out.java"
public class com.jwslh.clz.Out {
public com.jwslh.clz.Out();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
void testOut();
Code:
0: return
public static void main(java.lang.String[]);
Code:
0: new #2 // class com/jwslh/clz/Out
3: dup
4: invokespecial #3 // Method "<init>":()V
7: astore_1
8: return
}