I'm pretty sure that this is something to do with boxing/unboxing of the primitives. If you write generic code to work on primitives, you have to box the primitive and then unbox it at the place you've used it as a primitive. I am not sure what unboxing algorithm is used, but I suppose it is along the following lines:
if(box == null)
default value
else
box.unbox
Therefore, very strangely I might add, the default value of the field t
in your simple wrapper class is always going to be null
, as the field is always going to be a boxed primitive, as generics are implemented at the JVM level by type erasure. Therefore, all the JVM sees is that t
is of type Object
, with a value of null
. The method get
will therefore always return null
, but when the generic method get
is supposed to return a primitive type, the null
gets unboxed to the default value.
Also, a bit of poking around with reflection does indeed show that the field is indeed null
.
val sw = new SimpleWrap[Boolean]
sw.getClass.getDeclaredFields.map {
f => f.setAccessible(true)
f.get(sw)
}
Oh the fun of null
s. One solution to this problem would be to use the 2.8 @specialised
annotation, if that has been implemented in the nightly build you use.
Or, even better, the Scala compiler could default those fields to boxed defaults of the actual defaults of the primitives used. For example, in the case of a SimpleWrap[Boolean]
, t
would have the type Object
and the value java.lang.Boolean(false)
at runtime.
EDIT: Bug report submitted.
Another weird thing:
val x: Int = null.asInstanceOf[Int] // 0
val y: Boolean = null.asInstanceOf[Boolean] // false
This is something that should be solved in order for generics to really be generic, and have consistent behaviour! At the moment your get
method doesn't have a consistent behaviour.
-- Flaviu Cipcigan