I have the following method in java
protected <T> T getObjectFromNullableOptional(final Optional<T> opt) {
return Optional.ofNullable(opt).flatMap(innerOptional -> innerOptional).orElse(null);
}
It takes a java Optional that can itself be null (I know, this is really bad and we're going to fix this eventually). And it wraps it with another Optional so it becomes either Some(Optional<T>) or None. Then it's flatMapped, so we get back Optional<T> or None, and finally apply orElse() to get T or null.
How do I write the same method with the same java.util.Optional in scala?
protected def getObjectFromNullableOptional[T >: Null](opt : Optional[T]): T =
???
I tried
protected def getObjectFromNullableOptional[T >: Null](opt : Optional[T]): T =
Optional.ofNullable(opt).flatMap(o => o).orElse(null)
But this gives me a Type mismatch error
Required: Function[_ >: Optional[T], Optional[NotInferedU]]
Found: Nothing => Nothing
I tried
protected def getObjectFromNullableOptional[T >: Null](opt : Optional[T]): T =
Option(opt).flatMap(o => o).getOrElse(null)
But this gives me
Cannot resolve overloaded method 'flatMap'
Edit I neglected to mention I'm using scala 2.11. I believe @tefanobaghino's solution is for scala 2.13 but it guided me towards the right path. I put my final solution in comments under this solution
The last error raises a few suspicions: it looks like you're wrapping a Java
Optionalin a ScalaOption. I would have instead have expected this to have failed because you're trying toflatMapto a different type, something likeThis seems to fulfill your requirement:
You can play around with this here on Scastie.
Note that
asInstanceOfis compiled to a cast, not to an actual method call, so this code will not throw aNullPointerException.You can also go into something closer to your original solution by helping Scala's type inference a bit:
Or alternatively using Scala's
identity:For a solution using Scala's
Optionyou can do something very close:Note that going to your
flatMapsolution with Scala'sOptionallows you to avoid having to be explicit about the function type:I'm not fully sure about the specifics, but I believe the issue is that, when using
java.util.Optionalyou are passing a ScalaFunctiontoOptional.flatMap, which takes a JavaFunction. The Scala compiler can convert this automatically for you but apparently you have to be specific and explicit about type for this to work, at least in this case.A note about your original code: you required
Tto be a supertype ofNullbut this is not necessary.You have a better context regarding what you are doing, but as a general advice it's usually better to avoid having
nulls leak in Scala code as much as possible.