以下代码可以正确编译。
val a: Int = 1
val b = a.asInstanceOf[AnyRef]
这让我感到困惑,因为Int扩展了AnyVal,它不是子类而是AnyRef的同级对象。
但是,如果按如下方式使用归属:
val a: Int = 1
val b: AnyRef = a
没用
error: type mismatch;
found : Int
required: AnyRef
Note: an implicit exists from scala.Int => java.lang.Integer, but
methods inherited from Object are rendered ambiguous. This is to avoid
a blanket implicit which would convert any scala.Int to any AnyRef.
You may wish to use a type ascription: `x: java.lang.Integer`.
val b: AnyRef = a
我的理解:
asInstanceOf
在运行时执行,它迫使编译器认为val a是AnyRef。但是,归因于编译时,转换无法通过类型检查,因此我们遇到“类型不匹配”错误。
我的问题:
基本上,为什么转换在运行时起作用?
如果将AnyRef视为JVM中的java.lang.Object,那么AnyVal怎么样?它在运行时是对象吗?
(如果是,它的类型是什么?java.lang.Object?但是AnyVal是AnyRef的兄弟,不是吗?)
(如果没有,我们如何使用某些AnyVal的子类作为Object,例如Int,Double)
scala编译器有一些技巧吗?
最佳答案
这是由于自动装箱:
scala>val a: Int = 1
a: Int = 1
scala> a.getClass
res2: Class[Int] = int
scala> val b = a.asInstanceOf[AnyRef]
b: AnyRef = 1
scala> b.getClass
res1: Class[_ <: AnyRef] = class java.lang.Integer
通过强制转换为
AnyRef
(java.lang.Object
),可以触发从int到java.lang.Integer的自动装箱如果在JVM中将AnyRef视为
java.lang.Object
,那么AnyVal
呢?它在运行时是对象吗?
AnyRef
确实是java.lang.Object
的别名AnyVal
是“虚拟”类型,出于类型系统完整性的考虑,它仅在编译时存在。在运行时,扩展
AnyVal
的实例将转换为相应的本机类型(int
,double
等),除了String
会转到java.lang.String
本身会扩展java.lang.Object
但在JVM中具有特殊处理。但是
AnyVal
是AnyRef
的兄弟姐妹,不是吗?AnyVal
和AnyRef
都扩展了类型Any
,但它们彼此不扩展。scala编译器有一些技巧吗?
负载:)
有关Scala类型层次结构的更完整说明,建议您先阅读:http://docs.scala-lang.org/tutorials/tour/unified-types.html