作为测试,我写了这段代码:
object Ambig extends App {
def f( x:Int ) { println("Int" ) }
def f( x:String ) { println("String") }
f( null.asInstanceOf[Int ] )
f( null.asInstanceOf[String] )
f(null)
}
Run Code Online (Sandbox Code Playgroud)
我期望在最后一次调用f()时遇到错误,说这是不明确的.编译器接受了它,并产生了这个输出:
Int
String
String
Run Code Online (Sandbox Code Playgroud)
现在我猜这与Int不是AnyRef这一事实有关,因此f(null)的唯一f版本是f(x:String).但是,如果Int不能为null,则null.asInstanceOf [Int]是什么意思?repl说它是Int类型:
scala> :type null.asInstanceOf[Int]
Int
Run Code Online (Sandbox Code Playgroud)
但我真的不明白它是如何运作的.毕竟,如果我尝试将一个String转换为一个Int,那么所有的地狱都会崩溃:
scala> "foo".asInstanceOf[Int]
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source)
...
Run Code Online (Sandbox Code Playgroud)
当然这是预期的 - "foo"不能成为Int.但是两者都不能为null,那么为什么将int转换为Int工作呢?想必拳击某种形式,但类型仍然是Int,不能为null ...
我错过了什么?
axe*_*l22 48
转换null为a 的行为Int取决于完成它的上下文.
首先,如果你将a转换null为a Int,它实际上意味着一个盒装整数,其值为null.如果将表达式放在期望类型的上下文中Any(它被转换为Object场景后面,因为在JVM字节码中,没有办法引用具有相同引用的基本类型和引用类型),那么值不会进一步转换 - 这就是println(null.asInstanceOf[Int])打印的原因null.
但是,如果在期望基元Int(Java int)的上下文中使用相同的盒装整数值,它将转换为基元,并且null(作为引用类型的默认值)转换为0(基本类型的默认值) ).
如果一个通用的方法做了这个演员,那么,当然,你得到一个null回来.
但是,如果此方法是专用的,则其返回类型是Int(在这种情况下是原始整数),因此null: Any必须像以前一样将值转换为基元.
因此,运行:
object Test extends App {
println(null.asInstanceOf[Int])
def printit(x: Int) = println(x)
printit(null.asInstanceOf[Int])
def nullint[T] = null.asInstanceOf[T]
println(nullint[Int])
def nullspecint[@specialized(Int) T] = null.asInstanceOf[T]
println(nullspecint[Int])
}
Run Code Online (Sandbox Code Playgroud)
生产:
null
0
null
0
Run Code Online (Sandbox Code Playgroud)
Dan*_*ral 21
事情就是这样:asInstanceOf没有意义.这个方法的作用是告诉编译器STOP MAKING SENSE,并相信你在说什么.
现在,如果你想知道为什么它返回0,那是因为asInstanceOf工作AnyRef,而不是AnyVal.当应用于a时AnyVal,它将使用盒装版本,而盒装null值为0.