Вот более сжатая версия вашей проблемы:
scala> defaultValue[Boolean]: Any
res0: Any = null
scala> defaultValue[Boolean]: Boolean
res1: Boolean = false
Первая версия применяется при вызове res = defaultValue[U]
, поскольку, хотя U
имеет тип Boolean, res
имеетвведите Любой
Если вы скомпилируете эту маленькую программу, используя опцию -Xprint:all
object Test {
def defaultValue[U]: U = { class Default[U] {var default: U = _ }; new Default[U].default }
def main(args:Array[String]) {
val any = defaultValue[Boolean]: Any
println(any)
val bool = defaultValue[Boolean]: Boolean
println(bool)
}
}
Вы увидите это прямо перед фазой стирания, у вас есть:
val any: Any = (Test.this.defaultValue[Boolean](): Any);
scala.this.Predef.println(any);
val bool: Boolean = (Test.this.defaultValue[Boolean](): Boolean);
scala.this.Predef.println(bool)
Затем в конце фазы стирания:
val any: java.lang.Object = (Test.this.defaultValue(): java.lang.Object);
scala.this.Predef.println(any);
val bool: Boolean = (scala.Boolean.unbox(Test.this.defaultValue()): Boolean);
scala.this.Predef.println(scala.Boolean.box(bool))
Так что получается, что под капотом defaultValue[Boolean]
возвращает ноль в обоих случаях, но затем ноль распаковывается в ложькогда тип возвращаемого значения является логическим.Вы можете проверить это в REPL:
scala> Boolean.unbox(null)
res0: Boolean = false
scala> null.asInstanceOf[Boolean]
res1: Boolean = false
Редактировать: у меня была идея - не то, чтобы я ее рекомендовал.Не знаю, какой у вас вариант использования (res = false
мне кажется проще ..)
scala> def f[@specialized U] = { class X { var x: U = _ }; (new X).x }
f: [U]U
scala> var res: Any = _
res: Any = null
scala> def g[@specialized U] = { res = f[U]; f[U] }
g: [U]U
scala> g[Boolean]
res0: Boolean = false
scala> res
res1: Any = false