The scenario is that I need to access a value at least twice. I.e. I am using logger to keep track of what is happening in the application. I want to log the name of the object, that function is working on, and later on do something with the very same name(i.e check if it contains some string or put it into an array).
Storing the name in variable:
foo(Bar bar){
String name = bar.getName();
logger.info("I am working with "+name);
this.doSomethingWith(name);
}
Or calling getName() twice:
foo(Bar bar){
logger.info("I am working with "+bar.getName());
this.doSomethingWith(bar.getName());
}
I understand, that in the first scenario, I will create a new String, assign a value to it and then retrieve this value twice. This way I am using more memory resources, correct?
In second scenario, am I accessing object bar twice and then accessing it's name twice. I suppose this is not a DRY approach. But on the other hand I am not repeating myself in the memory, correct?
Which approach is better?
Personally, I prefer the second approach.
Indeed, I usually create temporary variable solely when necessary.
Martin Fowler ( http://en.wikipedia.org/wiki/Martin_Fowler ) also follows this guideline. He relates it within his book that I've read:
http://www.amazon.fr/Refactoring-Improving-Design-Existing-Code/dp/0201485672
A free extract of its book concerning this topic is here:
http://sourcemaking.com/refactoring/replace-temp-with-query
Some people would argue removing temporary variables could lead to performance issue.
As Martin Fowler says:
You may be concerned about performance in this case. As with other
performance issues, let it slide for the moment. Nine times out of
ten, it won’t matter. When it does matter, you will fix the problem
during optimization. With your code better factored, you will often
find more powerful optimizations, which you would have missed without
refactoring. If worse comes to worse, it’s very easy to put the temp
back.
But anyway, it's a matter of taste. Some people find more readable the first approach, others the second. I really prefer the second because I hate temporary variables adding lines for no real values :)
You are not using more memory in the first example, because String
is an immutable object. As such, any reference to a String is simply a pointer to the same object in memory.
The latter option also has some issues of thread safety where the result of getName()
might change between invocations. Though possibly unlikely, it is something you might want to take into consideration.
With that in mind, I would recommend the first option even though it is more "talky."
Note: It is also possible that getName()
is generated by computation, in which case you would actually end up with the second method using more memory than the first one.
Your Bar
should immutable class (for most of the cases). For immutable class these approaches are the same, so you choose whatever you like.
Any real problem will occur only if Bar
is mutable, so value of bar.name
can change between 2 reads. But this case will render using Bar
as domain object (which it's seem to be) senseless. You might work-around such cases by creating local copy of bar
at the top of foo()
. Then, again, once you have local copy of original bar
, you can choose whatever way you like more.
So, this is matter of taste. Yes, you could waste a tiny bit of memory for local reference in the first case, but most probably, JVM will optimize it away to make it look like 2nd way on byte-code level.