IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    null造型为值类型时为何不抛异常

    hongjiang发表于 2015-08-03 01:55:56
    love 0

    问题简化后看一下代码片段:

    // Number引用类型
    scala> def foo[T](t: T) = {  t.asInstanceOf[Number] }
    foo: [T](t: T)Number
    
    scala> foo(null)
    res3: Number = null
    
    // Int值类型
    scala> def foo[T](t: T) = {  t.asInstanceOf[Int] }
    foo: [T](t: T)Int
    
    scala> foo(null)
    res4: Int = 0
    
    // 其它值类型
    scala> class V(val i:Int) extends AnyVal
    defined class V
    
    scala> null.asInstanceOf[V]
    res10: V = V@0
    

    把 null 造型为java.lang.Number这种引用类型的时候没有问题,但造型为scala里的值类型时,为何不抛出异常?与直觉不符。背后是装箱,拆箱所致。

    在stackoverflow上也有讨论

    // 不涉及到unboxing
    scala> val a:Any = null.asInstanceOf[Int]
    a: Any = null
    
    // 涉及到unboxing
    scala> val a = null.asInstanceOf[Int]
    a: Int = 0  
    
    // 在scala.Int伴生对象里定义的运行时拆箱逻辑
    def unbox(x: java.lang.Object): Int = x.asInstanceOf[java.lang.Integer].intValue()
    

    另外,有人问为什么不抛出空指针异常,因为规范里是抛异常:

    asInstanceOf[T ] returns the “null” object itself if T conforms to scala.AnyRef,and throws a NullPointerException otherwise.
    A reference to any other member of the “null” object causes a NullPointerException to be thrown.

    这个规范已经更新了,2.10里的规范已经没有要求抛出异常了。

    https://issues.scala-lang.org/browse/SI-4437

    https://github.com/scala/scala-dist/pull/104



沪ICP备19023445号-2号
友情链接