def getOptionalIntegerFromConfig: Option[Int] = {
Option(methodFromJavaClassThatMayReturnANullInteger)
}
Caused by: java.lang.NullPointerException
at scala.Predef$.Integer2int(Predef.scala:357)
at com.package.Class$.getOptionalIntegerFromConfig(Class.scala:109)
I couldn't find anything in the bug tracker here on GitHub so I apologise if this is a known issue or not an issue or has been reported already
This looks like it's present in 2.11.8 but fixed in 2.12.1:
Welcome to Scala 2.11.8 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.
scala> def n: java.lang.Integer = null
n: Integer
scala> def o: Option[Int] = Option(n)
o: Option[Int]
scala> o
java.lang.NullPointerException
at scala.Predef$.Integer2int(Predef.scala:362)
at .o(<console>:12)
... 32 elided
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.
scala> def n: java.lang.Integer = null
n: Integer
scala> def o: Option[Int] = Option(n)
o: Option[Int]
scala> o
res0: Option[Int] = Some(0)
Maybe that was fixed in https://github.com/scala/scala/pull/5176
not sure I'd call that fixed, I imagine @KieranPringle was expecting None, not Some(0)
The Some(0) result is required to have correct handling of default values initialization(var x: T = _) under generics.
See example below
class C[T]{ var x: T = _ }
def n[T >: Null <: AnyRef](cont: C[T]): T = cont.x
Option(n(new C[Int])) // this won't compile as it will say that C[Int] isn't an AnyRef, because typer makes it look like C[Int] isn't the same as C[java.lang.Integer], but adding Java here will make it pass
Getting both right will require being able to distinguish null which is default value and a proper null. This distinction is very subtle.
Btw, under -Xlint it gives you a warning:
<console>:12: warning: Suspicious application of an implicit view (scala.Predef.Integer2int) in the argument to Option.apply.
Option[Int](null.asInstanceOf[java.lang.Integer])
(thanks to https://github.com/scala/scala/pull/1565)
Perhaps this can be called a duplicate of SI-6567.
I hadn't checked the version of Scala I was using, but I would have expected None. To me converting null to Some(0) seems a bit of a leap. It'd be worse in my situation (and many others) as if I make the call Option[Int](null.asInstanceOf[java.lang.Integer]).isDefined then I would get true! My code may assume that this means a legitimate value has been set and then proceed to use it, when what I was actually hoping for was an indication that this value was originally null
It's an interesting edge case I suppose! Happy to see it has created some discussion.
Most helpful comment
not sure I'd call that fixed, I imagine @KieranPringle was expecting
None, notSome(0)