2009-12-22 49 views
18

看看下面的例子:Java最終局部變量存儲在哪裏?

public void init() { 
    final Environment env = new Environment(); 
    Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
      env.close(); 
     } 
    }); 
} 

首先,在那裏被存儲env?是:

  • 由編譯器複製到內部類的隱藏成員變量引用它
  • 複製到,並參考上,堆
  • 留在堆棧上並以某種方式引用的有
  • 別的

猜測是第一個選項。

其次,做這樣做會產生任何性能問題(而不是簡單地創建env作爲類的成員變量並引用它),特別是如果您要創建大量引用最終本地的此類內部類結構變量。

回答

18

是的,它們被複制,這就是爲什麼你必須聲明變量爲final。這樣,它們保證在複製完成後不會改變。

這對於實例字段是不同的,即使不是最終字段也是可訪問的。在這種情況下,內部類將獲得對其用於此目的的外部實例的引用。

private Environment env; // a field does not have to be final 

public void init() { 
    Runtime.getRuntime().addShutdownHook(new Thread() { 
     public void run() { 
      env.close(); 
     } 
    }); 
} 

其次,這樣做從這樣產生的任何性能問題?

相比什麼?你需要讓內部類的字段或變量能夠工作,而副本是一種非常有效的方式。無論如何,它只是一個「淺」副本:只是對(在你的例子中)環境的引用被複制,而不是環境本身。

+0

那麼我可以假設這樣做沒有性能問題? – Joel 2009-12-22 11:08:42

+0

我的私人寵物在這方面是,對外部實例(用於訪問字段,而不是變量,被複制)的引用可能是一個問題,如果他們不需要:http://stackoverflow.com/questions/ 758570/is-it-it-possible-make-anonymous-inner-classes-in-java-static – Thilo 2009-12-22 11:15:30

+0

相比於將它引用爲成員變量。如果它被複制,那麼,我的假設是沒有性能影響。 – Joel 2009-12-22 11:17:00