2010-08-30 86 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

相关问题