16

While looking through the Java API source code I often see method parameters reassigned to local variables. Why is this ever done?

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

This is in java.util.HashMap

public Collection<V> values() {
  Collection<V> vs = values; 
  return (vs != null ? vs : (values = new Values())); 
}
initialZero
  • 6,197
  • 9
  • 29
  • 38
  • 6
    Could you please give us a few example methods to look at? – jjnguy Aug 30 '10 at 15:58
  • 2
    I think Doug Lea is known to do this in the `concurrent` package? Maybe I got that wrong, though (in which case I apologize). Related/dupe: http://stackoverflow.com/questions/3080074/why-would-anyone-make-additional-local-variable-just-to-put-final-keyword-on-it and http://stackoverflow.com/questions/2785964/in-arrayblockingqueue-why-copy-final-member-field-into-local-final-variable ; OK I got it slightly wrong, but Doug Lea does something similar with `final` local variables. – polygenelubricants Aug 30 '10 at 16:01
  • Possible duplicate of [Why it doesn't use the instance field directly, but assigns it to a local variable?](https://stackoverflow.com/questions/7943763/why-it-doesnt-use-the-instance-field-directly-but-assigns-it-to-a-local-variab) – anacron Jun 28 '17 at 09:33

2 Answers2

10

This is rule of thread safety/better performance. values in HashMap is volatile. If you are assigning variable to local variable it becomes local stack variable which is automatically thread safe. And more, modifying local stack variable doesn't force 'happens-before' so there is no synchronization penalty when using it(as opposed to volatile when each read/write will cost you acquiring/releasing a lock)

Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
Petro Semeniuk
  • 6,970
  • 10
  • 42
  • 65
  • But a method parameter is a local stack variable too. – user207421 Dec 17 '10 at 01:47
  • @EJP, @polygenelubricants. Good catch. In this case I fully agree that this part of question is covered in http://stackoverflow.com/questions/2785964/in-arrayblockingqueue-why-copy-final-member-field-into-local-final-variable (assuming that having final copy is not exclusively for inner class usage) – Petro Semeniuk Dec 17 '10 at 02:08
0

I'd have to look at some real examples, but the only reason I can think to do this is if the original value needs to be preserved for some computation at the end of the method. In this case, declaring one of the "variables" final would make this clear.

erickson
  • 265,237
  • 58
  • 395
  • 493
  • Nope, some people do this religiously. Not sure why either. – Dan Rosenstark Sep 05 '10 at 19:56
  • I finally found what I saw before. This is in java.util.HashMap public Collection values() { Collection vs = values; return (vs != null ? vs : (values = new Values())); } – initialZero Dec 17 '10 at 00:28
  • 1
    @initialZero - that's a member variable, rather than a method parameter, being copied to a local variable. This is a bit more common, especially in classes designed for concurrent access by multiple threads. However, `HashMap` is not such a class, so the only reason I can see is for "performance"; reading a local is faster than reading a member variable. However, it's not a big enough difference to justify obfuscating code like this, and they are only saving one read, and adding a local variable write, so I'm not sure if it would have any real benefit. – erickson Dec 17 '10 at 02:37