java.util.concurrent.ConcurrentMap's putIfAbsent
docs say the following about the return type:
the previous value associated with the specified key, or null if there was no mapping for the key.
On Scala 2.10.4, I tried to call putIfAbsent(Int, Int)
, i.e. with Scala's Int
type.
scala> import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.ConcurrentHashMap
scala> new ConcurrentHashMap[Int, Int]()
res0: java.util.concurrent.ConcurrentHashMap[Int,Int] = {}
scala> val x: Int = 1
x: Int = 1
Since 1
does not exist in the empty ConcurrentHashMap
, I would expect null
to return from a putIfAbsent(x, x)
call.
scala> res0.putIfAbsent(x, x)
res1: Int = 0
But, 0
gets returned. I'm assuming that null
gets converted to 0
.
What exactly is going on here? It seems odd to me that it's compiling.
Int
cannot be null
, nor can any AnyVal
. From the scaladoc:
Null is a subtype of all reference types; its only instance is the null reference. Since Null is not a subtype of value types, null is not a member of any such type. For instance, it is not possible to assign null to a variable of type scala.Int.
If we try it directly, we'll get an error:
scala> val i: AnyVal = null
<console>:9: error: type mismatch;
found : Null(null)
required: AnyVal
Note that implicit conversions are not applicable because they are ambiguous:
both method RichException in object Predef of type (self: Throwable)RichException
and method augmentString in object Predef of type (x: String)scala.collection.immutable.StringOps
are possible conversion functions from Null(null) to AnyVal
val i: AnyVal = null
The compiler instead fills it with the default value for Int
, which is 0
.
For example:
scala> def getNull[A](i: A): A = null.asInstanceOf[A]
getNull: [A](i: A)A
scala> getNull(1)
res6: Int = 0
Behind the scenes, we can't actually cast null
to an Int
, but it can be cast to a boxed type. However, once we use the boxed type in a context where it should be like the primitive it contains, it's converted to that type, which requires a default value.