繁体   English   中英

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

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

我有 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
  }
}

我想了解的是为什么Works.factoryWorks.factory序列化的,而Broken.factory不是?

要序列化一个类,所有成员也必须是可序列化的。 但是,请考虑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>();
      ()
    }
  }

特别注意成员

<synthetic> <paramaccessor> <artifact> private[this] val $outer: $line58.iw$A = _;

类实例的引用的$outerA ,但是trait A没有被宣布为Serializable 因此, Broken.factory引用的匿名类的序列化失败。

另一方面,考虑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>();
      ()
    }
  }

请注意,没有不是Serializable成员(类似于$outer )。 因此Works.factory引用的匿名类的序列化成功。

解决方法是使 trait A像这样可序列化

trait A extends Serializable { ... }

然而Java 对象序列化规范警告

出于多种原因,强烈建议不要对内部类(即,不是静态成员类的嵌套类)(包括本地类和匿名类)进行序列化。 因为在非静态上下文中声明的内部类包含对封闭类实例的隐式非瞬态引用,序列化这样的内部类实例也将导致其关联的外部类实例的序列化。

暂无
暂无

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

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