请注意,Serializable扩展Any,而不是AnyRef

时间:2014-11-07 02:04:54

标签: scala

以下代码:

def foo(s: java.io.Serializable): java.lang.Object = s

在scala 2.9.3下编译好了。但是在scala 2.10.4下得到了以下错误

scala> def foo(s: java.io.Serializable): java.lang.Object = s
<console>:7: error: type mismatch;
 found   : java.io.Serializable
 required: Object
Note that Serializable extends Any, not AnyRef.
Such types can participate in value classes, but instances
cannot appear in singleton types or in reference comparisons.
   def foo(s: java.io.Serializable): java.lang.Object = s

                                                        ^

我注意到commit添加了&#34; Any&#34; scala Serializable特征并认为它确实会对上述错误产生影响。

-trait Serializable extends java.io.Serializable
+trait Serializable extends Any with java.io.Serializable

但我很困惑,为什么这会产生影响。

1 个答案:

答案 0 :(得分:2)

自Scala 2.10起,您可以声明 value classes ,但没有创建任何实例,从而减少了运行时开销。值类是面向对象的一种等价于Java的原始类型。

Scala的类型层次结构以三种类型开头:根类型Any及其两个不同的子级AnyValAnyRef。在Scala 2.9之前,AnyVal无法扩展。 AnyRef相当于java.lang.Object。供参考:What are the relationships between Any, AnyVal, AnyRef, Object and how do they map when used in Java code?

来自Scala语言规范:

  

extends子句“使用mt_1扩展sc with with with mt_m”可以   省略,在这种情况下,假设“extends scala.AnyRef”。

Edit2:虽然此引用不直接应用于示例(extends-clause不为空),但我们可以非常确信没有Any的隐式继承。此外,java.io.Serializable肯定不会继承Any

结论

通过明确地扩展Any,实现Serializable的类现在也可以是值类。这似乎是有道理的,因为您可能希望序列化自定义值类。但是,这意味着Serializable的实例现在无法保证扩展AnyRef,因此可能与java.lang.Object不兼容。

修改:

简答:

Serializable extends java.io.Serializable 

等于

Serializable extends AnyRef with java.io.Serializable

不等于

Serializable extends Any with java.io.Serializable