I have this Java class in a Jar file included as a dependency of an Scala program (like the Axis jar):
class MyClass {
private String[] someStrings;
public String[] getSomeStrings() { return someStrings; }
}
In my Scala program I have a Java API that return an instance of MyClass instance of MyClass to my program in Scala:
val myInstance = JavaAPI.getInstanceOfMyClass()
Then I try to use the someStrings array in my Scala program but it's null (let say that it wasn't properly initialized)
for(str <- myInstance.getSomeStrings()) ...
So this throws a NullPointerException.
I've found that in order to use it in the for comprehension I can wrap it into an Option so that it handles the NPE properly.
for(str <- Option[Array[String]](myInstance.getSomeStrings).getOrElse(Array[String]())
But that doesn't look OK to me.
Is there a way to create like an implicit method that takes that value even if it's null and wrap it into the Option, like:
implicit def wrapNull(a: Null): Option[Nothing] = None
implicit def wrapArray(a: Array[String]): Option[Array[String]] = Some(a)
So that when I do:
for(str <- myInstance.getSomeStrings())
I don't get the NPE
I don't think your version with getOrElse
is that bad (you can make it a little shorter by removing the [Array[String]]
after Option
, since that can be inferred). If you want something even more concise, the following works:
for (str <- Option(myInstance.getSomeStrings).flatten) ...
You could also use the fact that Option
has a foreach
:
for {
strings <- Option(myInstance.getSomeStrings)
str <- strings
} ...
Note that you can't use yield
here, for the reason that drexin highlights in a comment below.
Or you could pimp MyClass
:
implicit def withNullWrapper(c: MyClass) = new {
def getSomeStringsOrNot() = Option(c.getSomeStrings).getOrElse(Array[String]())
}
for (str <- myInstance.getSomeStringsOrNot) ...