Scala-dev: NullPointerError on creating Option[Int] from null Java Integer

Created on 3 Apr 2017  路  7Comments  路  Source: scala/scala-dev

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

Most helpful comment

not sure I'd call that fixed, I imagine @KieranPringle was expecting None, not Some(0)

All 7 comments

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)

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

adriaanm picture adriaanm  路  6Comments

SethTisue picture SethTisue  路  5Comments

adriaanm picture adriaanm  路  3Comments

SethTisue picture SethTisue  路  4Comments

retronym picture retronym  路  5Comments