Why does the Double.valueof javadoc say it caches values, when it doesn't?
In OpenJDK, for the method:
public static Double valueOf(double d)
The javadoc says:
Returns a Double instance representing the specified double value. If a new Double instance is not required, this method should generally be used in preference to the constructor Double(double), as this method is likely to yield significantly better space and time performance by caching frequently requested values.
Here's the actual code:
public static Double valueOf(double d) {
return new Double(d);
}
The cache is a lie! What's going on here?
The method exists for many types: Integer
, Long
, BigDecimal
and others and the documentation is always the same: Under some circumstances (which aren't defined), the method can return the same result.
AFAIK, the caching is only implemented for integer types and it returns cached instances for values between -128 and 127 (most common values). For BigDecimal
, the cache currently works for values from 0 to 10.
Later versions of Java might extend this behavior to other values/more types. So it's smart to use this code today because it might make your code faster tomorrow (and the code won't be slower today).
The Java compiler, for example, uses this API when generating code for autoboxing.
There is nothing wrong with the API doc:
This method is likely to yield...
That is, an implementation is allowed to do caching here, which is simply not possible with a constructor. However, it is not required to. But, since chances are that you have an implementation that performs caching, this method should be preferred over using a constructor.
From Java 1.5+, the JVM/JIT guarantees the caching of Integer
s -127 to 127. So that is why for Integer
the preferred approach is to use valueOf
. You should generally use valueOf
over using the constructor for double
because then the JIT is able to optimise your code as it sees fit. For example, consider the following loop:
for (Object o: objectList) {
o.setValue(Double.valueOf(0.0));
}
In this instance, the JIT can precalculate the double object and reassign the same value on each iteration of the loop, whereas if you were to use new Double(0.0);
it would not be able to do that.
The designers of the API probably didn’t want to restrict alternate implementation. Those are now free to add caching to the Double
class.
These valueOf()
methods exist in every numeric type for the purpose to support caching. In fact, for Double it does not use any cache but for Integer
and Long
.