作为测试,我写了这个代码:
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)
}
我期待得到的F),上调用(错误,称这是不明确的。 编译器所接受它,并且产生这样的输出:
Int
String
String
现在,我猜,这与对于F(空)工作的事实,int是不是一个AnyRef,所以f的唯一版本做的是F(X:字符串)。 不过,如果int不能为空,这是什么null.asInstanceOf [INT]是什么意思? 该REPL说,这是一个int类型:
scala> :type null.asInstanceOf[Int]
Int
但我实在不明白它是如何工作。 毕竟,如果我试着投一个字符串为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)
...
当然,这是可以预料到的 - “富”不能做成一个int。 但无论是CAN空,所以为什么铸造空为int的工作? 想必拳以某种形式,但类型仍然是int,它不能为空...
我在想什么?
铸造的行为null
于Int
取决于其所完成的情况下。
首先,如果你投一个null
到Int
,它实际上指的是盒装的整数,其值是null
。 如果你把表达的情境,其中预期的类型是Any
(它被传递给Object
幕后,因为在JVM字节码,就没有办法来指代基本类型和引用类型具有相同的参考),然后该值未进一步转化-这就是为什么println(null.asInstanceOf[Int])
打印null
。
然而,如果使用在一个上下文中,这同样盒装整数值,其中一个原始Int
(爪哇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])
}
生产:
null
0
null
0
事情是这样的: asInstanceOf
没有什么意义。 什么这种方法确实是告诉编译器停止决策意识,相信你说的话。
现在,如果你想知道为什么它返回0,这是因为asInstanceOf
适用于AnyRef
,而不是AnyVal
。 当应用于AnyVal
,它将使用盒装版本,而是和装箱的null
具有0值。
它看起来像它只是自动将其转换到零:
scala> null.asInstanceOf[Int]
res0: Int = 0
而且,当然,0,不同于空,可以是一个Int
。
首先,我们都同意,我们不能将null
到scala.Int
在记录http://www.scala-lang.org/api/current/index.html#scala.Null
二,为什么当我们这样做println(null.asInstanceOf[Int])
它给null
?
这是因为的println的实施。 它最终调用的Java String.valueOf
方法,这是
return (obj == null) ? "null" : obj.toString();
如果你做一个null.asInstanceOf[Int] == null
的外壳,它将返回true,但它给出了一个相反的警告,“用'==”总是会产生错误的比较类型INT和空值”。 我想这可能是Scala的类型擦除问题。
做println
只需要一个scala.Any类型,所以铸造null.asInstanceOf[Int]
实际上还没有发生。 所以我们只需要记住,当你分配null.asInstanceOf[Int]
为int,剧组发生在基于Scala的删除语义运行,并将其分配0到它。
顺便说一句,你仍然可以做AF(空)没有任何编译错误,因为Scala是做一个隐式转换为你
null -> java.lang.Integer -> scala.Int
但是,你会看到它在运行时炸毁。