2010-08-30 128 views
11

在瀏覽Java API源代碼時,我經常看到方法參數被重新分配給局部變量。爲什麼會這樣做?爲什麼方法參數重新分配給局部變量?

void foo(Object bar) { 
    Object baz = bar; 
    //... 
} 

這是java.util.HashMap中

public Collection<V> values() { 
    Collection<V> vs = values; 
    return (vs != null ? vs : (values = new Values())); 
} 
+6

您能否請給我們看幾個示例方法? – jjnguy 2010-08-30 15:58:09

+1

我認爲Doug Lea被稱爲在'concurrent'包中執行此操作?也許我弄錯了,但(在這種情況下,我很抱歉)。相關/愚蠢:http://stackoverflow.com/questions/3080074/why-would-anyone-make-additional-local-variable-just-to-put-final-keyword-on-it和http:// stackoverflow。 com/questions/2785964/in-arrayblockingqueue-why-copy-final-member-field-into-local-final-variable;好的,我認爲它有點不對,但是Doug Lea和'final'局部變量有相似之處。 – polygenelubricants 2010-08-30 16:01:50

+0

[爲什麼不直接使用實例字段,但將其分配給本地變量?](https://stackoverflow.com/questions/7943763/why-it-doesnt-use-the-instance-字段直接但是分配它到一個本地變量) – anacron 2017-06-28 09:33:04

回答

4

這是線程安全/更好性能的規則。 valuesHashMap是易變的。如果您將變量分配給局部變量,它將變成自動線程安全的本地堆棧變量。此外,修改本地堆棧變量不會強制'發生之前',因此在使用它時不會產生同步損失(而不是在每次讀/寫操作會導致您獲取/釋放鎖時,會導致同步損失)

+0

但是方法參數也是一個本地堆棧變量。 – EJP 2010-12-17 01:47:48

+0

@EJP,@ polygenelubricants。接得好。在這種情況下,我完全同意問題的這一部分在http://stackoverflow.com/questions/2785964/in-arrayblockingqueue-why-copy-final-member-field-into-local-final-variable(假設有最終的副本不是專門用於內部類的使用) – 2010-12-17 02:08:04

0

我不得不看一些實際的例子,但唯一的原因,我能想到要做到這一點,如果原來的值需要在方法結束時進行一些計算。在這種情況下,聲明其中一個「變量」final會清楚地表明這一點。

+0

沒有,有些人虔誠地這樣做。不知道爲什麼。 – 2010-09-05 19:56:35

+0

我終於找到了我之前看到的。這是java.util.HashMap public Collection values(){ Collection vs = values; return(vs!= null?vs:(values = new Values())); } – initialZero 2010-12-17 00:28:27

+0

@initialZero - 這是一個成員變量,而不是一個方法參數,被複制到一個局部變量。這比較常見,尤其是在爲多線程併發訪問而設計的類中。然而,'HashMap'不是這樣一個類,所以我能看到的唯一原因就是「性能」;讀取本地比讀取成員變量更快。然而,這樣的代碼混淆並不是一個足夠大的差別,他們只保存一次讀取,並添加一個局部變量寫入,所以我不確定它是否會有任何實際的好處。 – erickson 2010-12-17 02:37:05

相關問題