Reputation: 999
I have Scala singleton objects Works
and Broken
that look very similar:
object Works {
def i = ???
val factory = new Serializable {
def get = i
}
}
object Broken extends A
trait A {
def i = ???
val factory = new Serializable {
def get = i
}
}
What I'd like to understand is why is Works.factory
serializable but Broken.factory
isn't?
Upvotes: 2
Views: 150
Reputation: 48420
To serialise a class all members must also be serialisable. However consider -Xprint:jvm
output of the anonymous new Serializable
in trait A
final class anon$1 extends Object with java.io.Serializable {
def get(): Nothing = anon$1.this.$outer.i();
<synthetic> <paramaccessor> <artifact> private[this] val $outer: $line58.iw$A = _;
def <init>($outer: $line58.iw$A): <$anon: Object> = {
if ($outer.eq(null))
throw null
else
anon$1.this.$outer = $outer;
anon$1.super.<init>();
()
}
}
In particular note the member
<synthetic> <paramaccessor> <artifact> private[this] val $outer: $line58.iw$A = _;
The class of instance referenced by $outer
is A
, however trait A
has not been declared as Serializable
. Therefore serialisation of anonymous class referenced by Broken.factory
fails.
On the other hand, consider -Xprint:jvm
output of the anonymous new Serializable
in object Works
final class anon$1 extends Object with java.io.Serializable {
def get(): Nothing = iw$Works.this.i();
def <init>(): <$anon: Object> = {
anon$1.super.<init>();
()
}
}
Notice there is no member (similar to $outer
) that is not Serializable
. Therefore serialisation of anonymous class referenced by Works.factory
succeeds.
The fix is to make trait A
serialisiable like so
trait A extends Serializable { ... }
however Java Object Serialization Specification warns
Serialization of inner classes (i.e., nested classes that are not static member classes), including local and anonymous classes, is strongly discouraged for several reasons. Because inner classes declared in non-static contexts contain implicit non-transient references to enclosing class instances, serializing such an inner class instance will result in serialization of its associated outer class instance as well.
Upvotes: 3