从学习java的时候知道匿名内部类能访问外部类的变量,那为何呢。先从一个最简答的例子开始:
public class InnerTest {
private int num = 0;
public static void main(String[] args) {
InnerTest innerTest = new InnerTest();
innerTest.inner();
}
public void inner() {
Thread thread = new Thread() {
public void run() {
System.out.println(num);
};
};
thread.start();
}
}
这个类会生成两个class文件
// Compiled from InnerTest.java (version 1.6 : 50.0, super bit)
class inner.InnerTest$1 extends java.lang.Thread {
// Field descriptor #6 Linner/InnerTest;
final synthetic inner.InnerTest this$0;
// Method descriptor #8 (Linner/InnerTest;)V
// Stack: 2, Locals: 2
InnerTest$1(inner.InnerTest arg0);
0 aload_0 [this]
1 aload_1 [arg0]
2 putfield inner.InnerTest$1.this$0 : inner.InnerTest [10]
5 aload_0 [this]
6 invokespecial java.lang.Thread() [12]
9 return
Line numbers:
[pc: 0, line: 1]
[pc: 5, line: 13]
Local variable table:
[pc: 0, pc: 10] local: this index: 0 type: new inner.InnerTest(){}
// Method descriptor #14 ()V
// Stack: 2, Locals: 1
public void run();
0 getstatic java.lang.System.out : java.io.PrintStream [20]
3 aload_0 [this]
4 getfield inner.InnerTest$1.this$0 : inner.InnerTest [10]
7 invokestatic inner.InnerTest.access$0(inner.InnerTest) : int [26]
10 invokevirtual java.io.PrintStream.println(int) : void [32]
13 return
Line numbers:
[pc: 0, line: 15]
[pc: 13, line: 16]
Local variable table:
[pc: 0, pc: 14] local: this index: 0 type: new inner.InnerTest(){}
Inner classes:
[inner class info: #1 inner/InnerTest$1, outer class info: #0
inner name: #0, accessflags: 0 default]
Enclosing Method: #27 #41 inner/InnerTest.inner()V
}
反编译InnerTest.class
public class inner.InnerTest {
// Field descriptor #6 I
private int num;
// Method descriptor #8 ()V
// Stack: 2, Locals: 1
public InnerTest();
0 aload_0 [this]
1 invokespecial java.lang.Object() [10]
4 aload_0 [this]
5 iconst_0
6 putfield inner.InnerTest.num : int [12]
9 return
Line numbers:
[pc: 0, line: 3]
[pc: 4, line: 5]
[pc: 9, line: 3]
Local variable table:
[pc: 0, pc: 10] local: this index: 0 type: inner.InnerTest
// Method descriptor #19 ([Ljava/lang/String;)V
// Stack: 2, Locals: 2
public static void main(java.lang.String[] args);
0 new inner.InnerTest [1]
3 dup
4 invokespecial inner.InnerTest() [20]
7 astore_1 [innerTest]
8 aload_1 [innerTest]
9 invokevirtual inner.InnerTest.inner() : void [21]
12 return
Line numbers:
[pc: 0, line: 8]
[pc: 8, line: 9]
[pc: 12, line: 10]
Local variable table:
[pc: 0, pc: 13] local: args index: 0 type: java.lang.String[]
[pc: 8, pc: 13] local: innerTest index: 1 type: inner.InnerTest
// Method descriptor #8 ()V
// Stack: 3, Locals: 2
public void inner();
0 new inner.InnerTest$1 [27]
3 dup
4 aload_0 [this]
5 invokespecial inner.InnerTest$1(inner.InnerTest) [29]
8 astore_1 [thread]
9 aload_1 [thread]
10 invokevirtual java.lang.Thread.start() : void [32]
13 return
Line numbers:
[pc: 0, line: 13]
[pc: 9, line: 18]
[pc: 13, line: 19]
Local variable table:
[pc: 0, pc: 14] local: this index: 0 type: inner.InnerTest
[pc: 9, pc: 14] local: thread index: 1 type: java.lang.Thread
// Method descriptor #40 (Linner/InnerTest;)I
// Stack: 1, Locals: 1
static synthetic int access$0(inner.InnerTest arg0);
0 aload_0 [arg0]
1 getfield inner.InnerTest.num : int [12]
4 ireturn
Line numbers:
[pc: 0, line: 5]
Inner classes:
[inner class info: #27 inner/InnerTest$1, outer class info: #0
inner name: #0, accessflags: 0 default]
}
可知这个类InnerTest$1持有了InnerTest的对象,具体在调用run方法的时候,会调用InnerTest.class中的静态方法 static synthetic int access$0(inner.InnerTest arg0);用对象arg0访问私有变量num.