0
public Double squareRoot(Double d)
{
return new Double (Math.sqrt(d.doubleValue()));
}

What is the purpose of "return new"? Would it still work if "new" was removed?

K G
  • 17
  • 5
  • 7
  • 1
    Do you understand what is going on and wondering for a reason why there is a 'new' or do you just ask? – Stefan Apr 03 '13 at 17:44
  • 1
    The `new` operator should never be used with primitive values. This is due to autoboxing, which you can find plenty of questions on already (like [this one](http://stackoverflow.com/questions/5199359/why-do-people-still-use-primitive-types-in-java)). – jbabey Apr 03 '13 at 17:47

4 Answers4

9

Yes, in fact you can remove even more code:

public Double squareRoot(Double d)
{
    return Math.sqrt(d);
}

Even though Math.sqrt returns a double and not a Double. This is done by a java feature called Autoboxing.

But as @assylias pointed out, you asked if it is ok to just remove the new keyword. The answer to that is no. This does not compile:

public Double squareRoot(Double d)
{
    return Double (Math.sqrt(d.doubleValue()));
}

The error is "Method call expected". You can't call a class' constructor as a method. You can only call a constructor by putting a new keyword in front of it.

Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356
2

You are not using something called 'return new', instead, the following code:

return new Double (Math.sqrt(d.doubleValue()));

actually does

  1. new Double (Math.sqrt(d.doubleValue())) (which creates a new Double object with the value of Math.sqrt(d.doubleValue())
  2. return value of step 1

Java also has a concept called autoboxing which allows for automatic conversion between objects of type Double and values of the type double. As result you don't need to explicitly create an object using new Double(...) because Math.sqrt(...) returns a value of double. Java will do that automagically for you. Same applies to the parameter d: you don't need to call doubleValue() on it.

So you can change the code to:

public Double squareRoot(Double d) {
   return Math.sqrt(d);
}

Or better yet use the primitive double as an object of type Double is not really necessary here:

public double squareRoot(double d) {
   return Math.sqrt(d);
}

Or better yet (as forivall pointed out in comments to another answer) don't bother with this method and simply call Math.sqrt(...) directly.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • Why is it necessary to create an object before returning the value? – K G Apr 03 '13 at 18:26
  • It isn't if you want to return a `double`, but if you want to return a `Double` (which is an immutable object), then there is choice but to create a new one. This can be done explicitly using `new Double(..)` or `Double.valueOf(..)` or implicitly using autoboxing from `double` to `Double`. – Mark Rotteveel Apr 04 '13 at 06:58
1

This new Double (Math.sqrt(d.doubleValue())); involves converting a primitive type double to its wrapper class Double, and the other way round. But it's unnecessary. Instead, you can do return Math.sqrt(d), which is an example of both autoboxing and unboxing.

"Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing."

http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

Shuo
  • 4,749
  • 9
  • 45
  • 63
0

Yes, it would still work (provided you also remove the brackets around Math.sqrt(d)) - as long as you're using Java 5 or newer. That feature is called autoboxing / auto-unboxing, meaning the JVM will automatically wrap a primitive in it's corresponding wrapper type.

However, the disadvantage of writing return new Double(Math.sqrt(d)) is that is slightly less efficient. If you use return Double.valueOf(Math.sqrt(d)) (or just return Math.sqrt(d); is that the first option will create a new Double object, whereas the latter two options will try to re-use an earlier created Double instance.

See the Double.valueOf() Javadoc for details.

mthmulders
  • 9,483
  • 4
  • 37
  • 54
  • Actually the current implementation of `Double.valueOf(..)` in (Oracle) Java 7 simply does `return new Double(d);` so it doesn't actually cache anything – Mark Rotteveel Apr 03 '13 at 17:53
  • Even for Java 7, the Javadoc clearly states it "is likely to yield significantly better space and time performance by caching frequently requested values". Maybe the native JVM code handles it? – mthmulders Apr 03 '13 at 18:19
  • Not as far as I know, if you look at the equivalent method in for example `Integer`, then that actually does handle the caching. – Mark Rotteveel Apr 03 '13 at 18:23
  • Interesting question... Technically, the Javadoc only _suggests_ that caching might occur, so there is no discrepancy between API docs and actual implementation :). – mthmulders Apr 03 '13 at 18:34
  • True, maybe when they designed the API they thought they would cache it, but then decide that wasn't feasible (which values are commonly used to cache and which aren't). For integral types that is a much easier decision. – Mark Rotteveel Apr 04 '13 at 07:01