如果 Int 不能为 null,null.asInstanceOf[Int] 是什么意思? [英] If an Int can't be null, what does null.asInstanceOf[Int] mean?

查看:52
本文介绍了如果 Int 不能为 null,null.asInstanceOf[Int] 是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As a test, I wrote this code:

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() 时得到一个错误,说它不明确.编译器接受了它,并产生了这个输出:

I was expecting to get an error on that last invocation of f(), saying that it was ambiguous. The compiler accepted it, and produced this output:

Int
String
String

现在我猜这与 Int 不是 AnyRef 的事实有关,所以唯一适用于 f(null) 的 f 版本是 f(x:String).但是,如果 Int 不能为 null,那么 null.asInstanceOf[Int] 是什么意思?repl 说它是 Int 类型:

Now I'm guessing that this has to do with the fact that Int is not an AnyRef, so the only version of f that works for f(null) is f(x:String). But then, if an Int can't be null, what does null.asInstanceOf[Int] mean? The repl says it's of type Int:

scala> :type null.asInstanceOf[Int]
Int

但我真的不明白它是如何工作的.毕竟,如果我尝试将 String 转换为 Int,一切都会崩溃:

but I don't really see how that works. After all, if I try to cast a String to an Int, all hell breaks loose:

scala> "foo".asInstanceOf[Int]
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Integer
    at scala.runtime.BoxesRunTime.unboxToInt(Unknown Source)
        ...

当然这是意料之中的——foo"不能变成一个 Int.但是两者都不能为 null,那么为什么将 null 转换为 Int 会起作用呢?大概是某种形式的装箱,但类型仍然是Int,不能为空...

Of course that's to be expected -- "foo" can't be made into an Int. But neither can null, so why does casting null to an Int work? Presumably boxing in some form, but the type is still Int, which can't be null...

我错过了什么?

推荐答案

null 转换为 Int 的行为取决于其完成的上下文.

The behaviour of casting null to an Int depends on the context in which it is done.

首先,如果将 null 转换为 Int,它实际上表示一个装箱整数,其值为 null.如果将表达式放在预期类型为 Any 的上下文中(在幕后转换为 Object,因为在 JVM 字节码中,无法引用到具有相同引用的原始类型和引用类型),则该值不会进一步转换 - 这就是 println(null.asInstanceOf[Int]) 打印 null 的原因.

First of all, if you cast a null to an Int, it actually means a boxed integer, whose value is null. If you put the expression in a context where the expected type is Any (which is translated to Object behind the scene, because in the JVM bytecode, there is no way to refer to a primitive type and a reference type with the same reference), then this value is not converted further - that is why println(null.asInstanceOf[Int]) prints null.

但是,如果您在需要原始 Int (Java int) 的上下文中使用相同的装箱整数值,它将被转换为原始值,并且null 被(作为引用类型的默认值)转换为 0(原始类型的默认值).

However, if you use this same boxed integer value in a context where a primitive Int (Java int) is expected, it will be converted to a primitive, and null is (as a default value for reference types) converted to 0 (a default value for primitive types).

如果一个泛型方法执行了这个转换,那么自然地,你会得到一个 null 返回.

If a generic method does this cast, then, naturally, you get a null back.

然而,如果这个方法是专门的,那么它的返回类型是 Int(在这种情况下是一个原始整数),所以 null: Any 值必须像以前一样转换为原始类型.

However, if this method is specialized, then its return type is Int (which is a primitive integer in this case), so the null: Any value has to be converted to a primitive, as before.

因此,运行:

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

这篇关于如果 Int 不能为 null,null.asInstanceOf[Int] 是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆