New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Creation of Option from java.lang values may cause a null pointer exception #9634
Comments
Imported From: https://issues.scala-lang.org/browse/SI-9634?orig=1 |
@SethTisue said: |
@SethTisue said (edited on Jan 29, 2016 6:57:34 PM UTC): And as for the possibility of carrying this thinking through to the rest of the language and standard library, I think that's a non-starter. The design of how Scala treats boxed Java types was settled at least a decade ago and the benefit would have to be very high indeed in order to justify the cost of pushing through such a fundamental change. The only change in this vein I can envision perhaps being accepted would be adding an additional method, not named |
@som-snytt said: scala> implicit class xxx(val o: Option.type) extends AnyVal {
| def longmire(v: java.lang.Long): Option[Long] =
| o(v) map (Long.unbox) }
|
@lrytz said: scala> (null: java.lang.Long): Long
java.lang.NullPointerException
at scala.Predef$.Long2long(Predef.scala:368)
... 28 elided |
As expressed in SO 33650809, the creation of
Option
from a null-carryingjava.lang
value can cause aNullPointerException
to be thrown.This is because the way
Option
factory is defined:What happens is that the
x
(being e.g.java.lang.Long
- and carrying a null) is first implicitly converted toscala.Long
, before being compared to null.scala.Long
is anAnyVal
and cannot thus carry a null. Thus the exception.I would see two ways to fix this unexpected behaviour, as explained in my proto pull request.
The approach I would like to see in future Scala versions is a guarantee that an
Option
will never carry ajava.lang
value, but the corresponding ScalaAnyVal
. I.e. one could not create anOption[java.lang.Long]
, at all. This makes sense since the use ofOption
is often used at Java/Scala borders, to filter outnull
s. If the value is not null, we can just as well represent it as a ScalaAnyVal
. This change would only make the guarantee ofOption
stronger.Also, the way an IDE can obscure the difference between
scala.Long
andjava.lang.Long
from the user (showing both as simplyLong
), this would help managing conversions in general. Creating anOption
from ajava.lang.Long
would create anOption[scala.Long]
, which is what APIs likely would be expecting. Without this change, one gets weird error messages such as "expectingOption[Long]
but hadOption[Long]
".The other way to solve the NullPointerException problem would be to use two type parameters to
Option
, allowing the test againstnull
to precede the implicit conversion. This, however, would break code that explicitly provides one (target) template argument forOption
. It would also allowOption[java.lang.Long]
to be created, leading to the above compilation issues.The text was updated successfully, but these errors were encountered: