简体   繁体   English

Scala 单例对象中值的 Java 序列化

[英]Java serialization of a value in a Scala singleton object

I have Scala singleton objects Works and Broken that look very similar:我有 Scala 单例对象WorksBroken ,它们看起来非常相似:

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?我想了解的是为什么Works.factoryWorks.factory序列化的,而Broken.factory不是?

To serialise a class all members must also be serialisable.要序列化一个类,所有成员也必须是可序列化的。 However consider -Xprint:jvm output of the anonymous new Serializable in trait A但是,请考虑trait A匿名new Serializable -Xprint:jvm输出

  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 .类实例的引用的$outerA ,但是trait A没有被宣布为Serializable Therefore serialisation of anonymous class referenced by Broken.factory fails.因此, Broken.factory引用的匿名类的序列化失败。

On the other hand, consider -Xprint:jvm output of the anonymous new Serializable in object Works另一方面,考虑object Works匿名new Serializable -Xprint:jvm输出

  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 .请注意,没有不是Serializable成员(类似于$outer )。 Therefore serialisation of anonymous class referenced by Works.factory succeeds.因此Works.factory引用的匿名类的序列化成功。

The fix is to make trait A serialisiable like so解决方法是使 trait A像这样可序列化

trait A extends Serializable { ... }

however Java Object Serialization Specification warns然而Java 对象序列化规范警告

Serialization of inner classes (ie, 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.因为在非静态上下文中声明的内部类包含对封闭类实例的隐式非瞬态引用,序列化这样的内部类实例也将导致其关联的外部类实例的序列化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM