Reputation: 21
I am trying to test for a null input at the start of the method. And if found true I want to return null even though the method would usually return doubles.
I need to keep the type of method as double
public double computeMean (double[] grades) {
if (grades == null) {
return null;
Cannot convert from null to double
Upvotes: 2
Views: 6787
Reputation: 25903
null
is a value that can only be used for objects. A double
however is a primitive, it does not use the object-system. Which is why you can not return null
if you specified double
as return type.
So, what are your options?
Double
wrapperYou can instead use Double
, the wrapper class for double
which uses the object-system.
Since Java provides automatic conversion between double
and Double
whenever needed (autoboxing), this can be quite handy to use.
Note that using Double
brings quite some overhead to just a small double
and that people regularly tend to forget to check for null
when converting a Double
to a double
. I.e.
// foo() returns Double
double value = foo(); // Bad code, it could be null!
Instead, users must remember to check the resulting value:
Double result = foo();
if (result == null) {
...
} else {
double value = result;
...
}
OptionalDouble
The modern, and probably better alternative, is to use Optional
(you need at least Java 8 for this).
It was designed to be used whenever a method naturally might sometimes not return a result. For example if the array passed in empty. That case is completely okay and not to be considered as error.
This also solves the problem of users forgetting to check the result. Optional
forces them to check it, else they can not get hands on the underlying value.
In order to avoid the performance overhead of Optional<Double>
(wrapper class again), there is also OptionalDouble
which internally uses double
(primitive). Here is the code:
public OptionalDouble computeMean(double[] grades) {
if (grades == null) {
return OptionalDouble.empty();
}
...
return OptionalDouble.of(result);
}
And the usage:
OptionalDouble result = computeMean(...);
From there the user has a couple of options (see the documentation), for example
double value = result.orElse(10.4);
// or
double value = result.orElseThrow();
// or
if (!result.isPresent()) {
...
} else {
double value = result.getAsDouble();
}
The last option is to actually just throw an exception. You should consider this whenever an user is doing something that is not intended and against what you consider correct usage (indicate this in your methods documentation).
I would actually say that in your specific situation, this is the case. It is impossible to compute a mean
on null
. It is different to passing in an empty array, where the I would go for an empty Optional
. For a null
array I would throw an exception, to indicate a bad usage.
A good exception for this situation is IllegalArgumentException
, here is the code:
public double computeMean(double[] grades) {
if (grades == null) {
throw IllegalArgumentException("Grades must not be null!");
}
...
}
Another idiomatic exception for exactly this use case is to throw NullPointerException
. There is even a compact helper method to do all of this in one line:
public double computeMean(double[] grades) {
Objects.requireNonNull(grades); // Yes, thats it
...
}
Putting all of that together, I would do the following two changes:
NullPointerException
if grades
is null
, using Objects#requireNonNull
OptionalDouble
if grades
is emptypublic OptionalDouble computeMean(double[] grades) {
Objects.requireNonNull(grades);
if (grades.length == 0) {
return OptionalDouble.empty();
}
...
return OptionalDouble.of(result);
}
Upvotes: 4
Reputation: 567
You should use
Double
wrapper class(mind the uppercase "d")
not double
primitive type as your return type, if you want to be able to return null
.
Upvotes: 2