[英]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.