匿名内部类为何能访问外部类的变量

从学习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.

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值