Why do the default values here behave differently when assigned explicitly to a val, versus printed directly?
package blevins.example
class SimpleWrap[T] {
var t: T = _
def get = t
}
object App extends Application {
val swb = new SimpleWrap[Boolean]
val b = swb.get
println("b: " + b) // b: false
println("swb.get: " + swb.get) // swb.get: null
val swi = new SimpleWrap[Int]
val i = swi.get
println("i: " + i) // i: 0
println("swi.get: " + swi.get) // swi.get: null
}
I’m using 2.8r19890.
Edit – It seems the strangeness happens when “get” is called expecting an Any.
val any1: Any = swb.get
val any2: Any = b
println("any1: " + any1) // any1: null
println("any2: " + any2) // any2: false
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:
Therefore, very strangely I might add, the default value of the field
tin your simple wrapper class is always going to benull, 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 thattis of typeObject, with a value ofnull. The methodgetwill therefore always returnnull, but when the generic methodgetis supposed to return a primitive type, thenullgets unboxed to the default value.Also, a bit of poking around with reflection does indeed show that the field is indeed
null.Oh the fun of
nulls. One solution to this problem would be to use the 2.8@specialisedannotation, 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],twould have the typeObjectand the valuejava.lang.Boolean(false)at runtime.EDIT: Bug report submitted.
Another weird thing:
This is something that should be solved in order for generics to really be generic, and have consistent behaviour! At the moment your
getmethod doesn’t have a consistent behaviour.— Flaviu Cipcigan