Java 内部类持有外部类的引用
·
文章目录
Java 内部类持有外部类的引用
常用命令
编译:javac Demo.java 生成 class 文件
查看外部类字节码:javap -c -p OuterClass.class
查看内部类字节码:javap -c -p OuterClass$InnerClass.class
源码
class OuterClass {
private int privateField = 10;
private void privateMethod() {
System.out.println("这是一个私有方法");
}
class InnerClass {
public void accessOuter() {
System.out.println(privateField);
privateMethod();
}
}
}
public class Demo {
public static void main(String[] args) {
OuterClass outer = new OuterClass();
OuterClass.InnerClass inner = outer.new InnerClass();
inner.accessOuter();
}
}
字节码
执行 javac Demo.java 生成3个文件:
- Demo.class
- OuterClass.class:外部类的class文件
- OuterClass$InnerClass.class:内部类的class文件
执行 javap -c -p OuterClass.class 输出字节码:
Compiled from "Demo.java"
class com.test.lib_java.OuterClass {
private int privateField;
com.test.lib_java.OuterClass();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: bipush 10
7: putfield #7 // Field privateField:I
10: return
private void privateMethod();
Code:
0: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #19 // String privateMethod
5: invokevirtual #21 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
}
执行 javap -c -p 'OuterClass$InnerClass.class' 输出字节码:
Compiled from "Demo.java"
class com.test.lib_java.OuterClass$InnerClass {
final com.test.lib_java.OuterClass this$0; // 持有外部类的引用
// 构造函数接收外部类的引用
com.test.lib_java.OuterClass$InnerClass(com.test.lib_java.OuterClass);
Code:
0: aload_0
1: aload_1
2: putfield #1 // Field this$0:Lcom/test/lib_java/OuterClass;
5: aload_0
6: invokespecial #7 // Method java/lang/Object."<init>":()V
9: return
public void accessOuter();
Code:
0: getstatic #13 // Field java/lang/System.out:Ljava/io/PrintStream;
3: aload_0
4: getfield #1 // Field this$0:Lcom/test/lib_java/OuterClass;
7: getfield #19 // Field com/test/lib_java/OuterClass.privateField:I
10: invokevirtual #25 // Method java/io/PrintStream.println:(I)V
13: aload_0
14: getfield #1 // Field this$0:Lcom/test/lib_java/OuterClass;
17: invokevirtual #31 // Method com/test/lib_java/OuterClass.privateMethod:()V
20: return
}
说明在编译器:
-
有多少个类生成多少个 .class 文件
-
内部类的类名变为
外部类名$内部类名的形式 -
内部类中持有一个 final 类型的外部类引用,通常命名为
this$0 -
内部类的构造函数被修改了,外部类实例作为参数传入
-
内部类直接访问外部类私有字段:
7: getfield #19 // Field com/test/lib_java/OuterClass.privateField:I -
内部类直接访问外部类私有方法:
17: invokevirtual #31 // Method com/test/lib_java/OuterClass.privateMethod:()V
更多推荐



所有评论(0)