6

Given following code:

val javaLong: java.lang.Long = null
val opt: Option[Long] = Option(javaLong)

I expected opt to be None but for some reason it is Some(0). I also found this bug and it appears that implicit conversion happens before option's apply method. I think this is still a bug because one wouldn't expect that behavior and I am wondering is there any workaround or some better ways to wrap nulls.

Update: The code above is only a simplified piece. The real example is something like:

Person(Option(doc.getLong()))

where Person is:

 case class Person(id: Option[Long])

and method doc.getLong() is java method that returns java.lang.Long

0

1 Answer 1

3

The conversion to Option[Long] is actually not just a conversion to an Option but also an implicit cast to Scala's Long from Java's Long.

val javaLong: java.lang.Long = null
// javaLong: Long = null

val long: java.lang.Long = javaLong
// long: Long = null
val long: Long = javaLong
// long: Long = 0

First we have the implicit conversion from Java's Long to Scala's Long which apparently produces 0 out of null.

Only then do we have the conversion to an Option.

If we specify Java's Long as a type of our Option then we do get None and not Some(0):

val opt: Option[java.lang.Long] = Option(javaLong)
// opt: Option[Long] = None (here it's Java's Long)

And we can finally cast the Option[java.lang.Long] to use Scala's Long:

val opt: Option[Long] = Option(javaLong).map(_.toLong)
// opt: Option[Long] = None (here it's Scala's Long)
Sign up to request clarification or add additional context in comments.

6 Comments

Yes, but the problem appears when it used in single line code in constructor. I updated the question
You might want to create an intermediate variable
I think it won't help. val l:Long = javaLong will produce 0. And Option[java.lang.Long] is not the same as Option[Long]
You can map the resulting Option[java.lang.Long] to Scala's Long: Option(javaLong).map(_.toLong). Person(Option(javaLong).map(_.toLong)) results in Person(None)
Option is working as expected, the oddity is expecting java.lang.Long and Long to be the same when one can be null and the other can't! You would have the same problem with any generic that tested for null values.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.