[英]What exactly happens when you have final values and inner classes in a method?
我遇到过很多需要将值传递给另一个线程的情况,我发现我可以这样做,但我一直想知道它是如何工作的?
public void method() {
final EventHandler handle = someReference;
Thread thread = new Thread() {
public void run() {
handle.onEvent();
}
};
thread.start();
}
编辑:只是意识到我的问题并没有完全指向我想知道的事情。 它更“工作”,而不是“为什么”。
没有方法可以访问其他方法的局部变量。 这包括匿名类的方法,如示例中的方法。 也就是说,匿名Thread类中的run
方法无法访问method()
的局部变量。
在本地变量前写入final
是一种让程序员让编译器知道变量实际上可以被视为值的方法。 由于此变量(读取值!)不会更改,因此在其他方法中访问它是“可以的”。
你可以通过简单地反编译内部类来注意下面发生的事情。 这是一个简短的例子:
编译完这段代码后:
public class Test {
public void method() {
final Object handle = new Object();
Thread thread = new Thread() {
public void run() {
handle.toString();
}
};
thread.start();
}
}
你会得到Test.class
为Test.java
和Test$1.class
在内部类Test.java
。 反编译Test$1.class
你会看到:
class Test$1 extends Thread
{
final Test this$0;
private final Object val$handle;
public void run()
{
this.val$handle.toString();
}
}
正如你所看到的那样,而不是handle
变量有this.val$handle
。 这意味着handle
被复制为val$handle
字段到内部类。 只有当handle
永远不会改变时,这才能正常工作 - 这在Java中意味着它必须是final
。
您还可以注意到内部类有一个this$0
字段,它是对外部类的引用。 这反过来说明了非静态内部类如何与外部类进行通信。
这个内部类被转换为类似于的代码:
class InnerClass extends Thread {
private EventHandler handle;
public InnerClass(EventHandler handle) {
this.handle = handle;
}
public void run() {
handle.onEvent();
}
}
...
EventHandler handle = someReference;
Thread thread = new InnerClass(handle);
thread.start();
由于内部类实际上传递了最终变量的副本,因此它不能对外部类中可见的任何更改。 要禁止甚至尝试更改此参数,只允许访问内部类中的最终变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.