There is no Double.valueOf(long)
.
What's actually happening in your first example is that now - then
is being computed, the result is long
, then it is implicitly being cast to a double
and passed to Double.valueOf(double)
. Basically, it is this:
double timeElapsed = Double.valueOf((double)(now - then)).doubleValue() / 1000;
As you can see, that serves no purpose! Note also that auto-unboxing will automatically convert a Double
to a double
, and so the doubleValue()
also serves no purpose.
The cast is the correct approach:
double timeElapsed = (double)(now - then) / 1000.0;
Which, as long as you use 1000.0
instead of 1000
, is equivalent to:
double timeElapsed = (now - then) / 1000.0;
The purpose of Double.valueOf(double)
, by the way, is just to give you a way to explicitly box a double
and convert it to a Double
if you need to. The purpose of doubleValue()
is the opposite. Neither are appropriate for your scenario. (This applies in general to all of the valueOf
/ *Value
methods on primitive wrapper classes.)
By the way, to reduce risk of precision loss (not a big risk in your case but in general), it is generally better to do the above than:
double timeElapsed = ((double)now - (double)than) / 1000.0;
Some explanation of what is happening in your example can be found here. Widening primitive conversions are allowed to happen automatically, and the JLS classifies long
to double
as a widening conversion.
However, there are risks in the long
to double
case, the primary risk being that not all values of a long
can be represented by a double
, and information can be silently lost in the conversion. Consider the following simple test (run it at http://ideone.com/zCmQzg):
for (long a = 1; ; a *= 7) {
long x = Double.valueOf(a).longValue();
if (x != a) {
System.out.println("Conversion fails at input=" + a + " output=" + x);
break;
}
}
This test will fail at certain values (e.g. Double.valueOf(11398895185373143L)
is not what you expect), becoming guaranteed as as the base-2 mantissa of the long
exceeds the range of the mantissa of a double
. Another simple test:
long x = 123456789123456789L;
System.out.println(x);
System.out.println(String.format("%20f", Double.valueOf(x))); // implicit
System.out.println(String.format("%20f", (double)x)); // explicit, same thing
Output:
123456789123456789
123456789123456784.000000
123456789123456784.000000
Note the final digit.
This danger exists any time you convert an integer to a double, including in my examples above - however, it is worth noting because passing a long
to a Double.valueOf()
, in my opinion, can catch one off guard more than the others.