下面是一个范例的示例。这里,将 TalkingClock 布局器的参数 interval beep移至 start 方法
public void start(int interval ,boolean beep){class TimePrinter implements ActionListener{ public void actionPerformed(ActionEvent event){ System.out.println("At the tone, the time is " + Instant.ofEpochMilli(event.getWhen())); if(beep) Toolkit.getDefaultToolkit().beep(); } } var listener = new TimePrinter(); var timer = new Timer(interval, listener); timer.start();}
请把稳,TalkingClock类不再须要存储 beep 实例字段。它只是引用 start 方法的 beep 参数变量
这看起来彷佛没什么值得大惊小怪的。毕竟,下面这行代码

if(beep) ...
末了总会在start 方法中,为什么不能访问 beep 变量的值呢?
为了能够清楚地看到这里一个奇妙的问题,让我们仔细考虑这个掌握流程。
调用start 方法。调用内部类 TimePrinter 的布局器,从而初始化工具变量 listener。将listener 引用通报给Timer 布局器,定时器开始计时,start 方法退出。此时start方法的beep 参数变量不复存在。1秒之后,actionPerformed 方法实行 if(beep) ...。要让actionPerfomed 方法中的代码正常事情,TimePrinter 类必须在 beep 参数值消逝之前状字复制为 start 方法的一个局部变量。实际上也是这样做的。在我们的例子中,编译器局部内部类合成了名字Talkinglock$TimePrinter。如果再次利用 ReflectionTest 程序或者 javap查看TalkingClocksTine Printer 类,就会看到以下结果:
class TalinglocsiTinefrinter{TalkingCloci$TimePrinter();public void actionPerfommed(jara.awt.event.ActionEvent);final boolean val$beep; final TalkingClock this$0; }
创建一个工具的时候,beep 变量确当前值会存储在 val$beep 字段中。在 Java 11 中,可以利用“嵌套伴侣”(nest mate) 访问来实现。之前,内部类布局器有一个额外的参数来设置这个字段。不论采取哪种方法,纵然局部变量出了浸染域,内部类字段都将持久保存。