Jiezhen Yi
Jiezhen Yi

Reputation: 125

Note that Serializable extends Any, not AnyRef

For the following code:

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

It is compiled okay under scala 2.9.3. But got the following error under 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

                                                        ^

I did notice this commit adds the "Any" to scala Serializable trait and think it does have impact for the above error.

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

But I am confused why this is making a difference.

Upvotes: 1

Views: 1371

Answers (1)

Kulu Limpa
Kulu Limpa

Reputation: 3541

Since Scala 2.10, you can declare value classes, for which no instances are created, leading to less runtime overhead. Value classes are kind of the object-oriented equivalent to Java's primitive types.

Scala's type hierarchy starts with three types: The root type Any and its two distinct children AnyVal and AnyRef. Until Scala 2.9, AnyVal could not be extended. AnyRef is equivalent to java.lang.Object. For reference: What are the relationships between Any, AnyVal, AnyRef, Object and how do they map when used in Java code?

From the Scala language specification:

The extends clause "extends sc with mt_1 with ... with mt_m" can be omitted, in which case "extends scala.AnyRef" is assumed.

Edit2: While this quote does not apply directly to the example (the extends-clause is not empty), we can be quite confident that there is no implicit inheritance of Any. Furthermore, java.io.Serializable surely does not inherit Any.

Conclusion

By explicitely extending Any, a class that implements Serializable can now also be a value class. This seems to make sense, as you may want to serialize your custom value classes. However, this means that an instance of Serializable is now not guaranteed to extend AnyRef, and therefore may not be compatible with java.lang.Object.

Edit:

Short answer:

Serializable extends java.io.Serializable 

is equal to

Serializable extends AnyRef with java.io.Serializable

which is not equal to

Serializable extends Any with java.io.Serializable

Upvotes: 2

Related Questions