If an Int can't be null, what does null.asInst

2019-05-14 13:30发布

作为测试,我写了这个代码:

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,它不能为空...

我在想什么?

Answer 1:

铸造的行为nullInt取决于其所完成的情况下。

首先,如果你投一个nullInt ,它实际上指的是盒装的整数,其值是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


Answer 2:

事情是这样的: asInstanceOf没有什么意义。 什么这种方法确实是告诉编译器停止决策意识,相信你说的话。

现在,如果你想知道为什么它返回0,这是因为asInstanceOf适用于AnyRef ,而不是AnyVal 。 当应用于AnyVal ,它将使用盒装版本,而是和装箱的null具有0值。



Answer 3:

它看起来像它只是自动将其转换到零:

scala> null.asInstanceOf[Int]
res0: Int = 0

而且,当然,0,不同于空,可以是一个Int



Answer 4:

首先,我们都同意,我们不能将nullscala.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

但是,你会看到它在运行时炸毁。



文章来源: If an Int can't be null, what does null.asInstanceOf[Int] mean?
标签: scala null