簡體   English   中英

在方法中有最終值和內部類時會發生什么?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM