可以编译以下代码而不会出现错误.
val a: Int = 1
val b = a.asInstanceOf[AnyRef]
Run Code Online (Sandbox Code Playgroud)
这让我感到困惑,因为Int扩展了AnyVal,它不是子类,而是AnyRef的兄弟.
但是,如果使用ascription如下:
val a: Int = 1
val b: AnyRef = a
Run Code Online (Sandbox Code Playgroud)
它不起作用.
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
Run Code Online (Sandbox Code Playgroud)
我的理解是:
asInstanceOf
在运行时执行,它迫使编译器相信val a是AnyRef.但是,归属是在编译时,转换不能通过类型检查,所以我们有一个"类型不匹配"错误.
我的问题:
这是因为自动装箱:
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
Run Code Online (Sandbox Code Playgroud)
通过强制转换为AnyRef
(java.lang.Object
),您可以触发从int到java.lang.Integer的自动装箱
如果AnyRef被认为是
java.lang.Object
在JVM中,那怎么样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