内部类说明

内部类说明

jdk版本:

java version “1.8.0_261”
Java(TM) SE Runtime Environment (build 1.8.0_261-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, mixed mode)

编译文件说明

  1. 内部类实际会被编译成【外部类名$内部类名.class】的字节码文件,并自动在内部类中生成一个持有外部类的【final 外部类名 this$0】的变量,由构造函数进行赋值
  2. 内部接口生成的字节码文件与第一点同理,并对接口函数进行【public abstract】声明
  3. 匿名内部类则会将类名赋予数字的形式处理,如【外部类名$1.class】,构造函数与第一点相同,如果有调用外部函数变量,则还会在构造函数增加该函数变量参数,并复制给【final 类型 val$别名】的变量上
  4. 如果内部类有调用外部类变量,则会在外部类生成一个静态函数【static 该外部类变量 access$000(外部类实例)】供内部类在调用外部类的地方使用

注:以上提到的美元符号的名命【this$0 access$000 val$name】在不同的编译器和调用情况会有所不同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// file name:Handler.java
// 源文件
public class Handler {
private String mName;
public void handle(String name) {// 匿名内部类有调用该参数,编译时会被声明为final
mName = name;
new RealHandler().handle();
// 匿名内部类
new IntHandler(){
@Override
public void handle() {
System.out.println(name); // 匿名内部类调用外部函数变量
}
};
}
// 内部类
public class RealHandler {
void handle() {
System.out.println(mName); // 内部类调用外部变量
}
}
// 内部接口
public interface IntHandler{
void handle();
}
}

外部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// file name:Handler.class
// 反编译文件
public class Handler {
private String mName;
public Handler() {
}
public void handle(final String var1) {
this.mName = var1;
(new Handler.RealHandler()).handle();
Handler.IntHandler var10001 = new Handler.IntHandler() {
public void handle() {
System.out.println(var1);
}
};
}
public interface IntHandler {
void handle();
}
public class RealHandler {
public RealHandler() {
}
void handle() {
System.out.println(Handler.this.mName);
}
}
}

// javap 命令文件
public class Handler {
public Handler();
public void handle(java.lang.String);
static java.lang.String access$000(Handler);
}

匿名内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// file name:Handler$1.class
// 反编译文件
import Handler.IntHandler;
class Handler$1 implements IntHandler {
Handler$1(Handler var1, String var2) {
this.this$0 = var1;
this.val$name = var2;
}
public void handle() {
System.out.println(this.val$name);
}
}

// javap 命令文件
class Handler$1 implements Handler$IntHandler {
final java.lang.String val$name;
final Handler this$0;
Handler$1(Handler, java.lang.String);
public void handle();
}

内部接口

1
2
3
4
5
6
7
8
9
// file name:Handler$IntHandler
// 反编译文件
public interface Handler$IntHandler {
void handle();
}
// javap 命令文件
public interface Handler$IntHandler {
public abstract void handle();
}

内部类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// file name:Handler$RealHandler.class
// 反编译文件
public class Handler$RealHandler {
public Handler$RealHandler(Handler var1) {
this.this$0 = var1;
}
void handle() {
System.out.println(Handler.access$000(this.this$0));
}
}
// javap 命令文件
public class Handler$RealHandler {
final Handler this$0;
public Handler$RealHandler(Handler);
void handle();
}