jpg4.us

 

2008/09/20 - るいもの戯れ言
PR: 転職    葬式    マンスリーマンション 神戸    北海道    環境    FX    不動産担保融資    桐ヶ谷斎場    海外旅行    専門学校   

scala.Enumerationの直列化

2.7.2 RC2で直列化できるようになったので、試してみた。

import java.io._

object MyEnum extends test.Enumeration {
  val One = Value("One")
  val Two = Value("Two")
}

object Test {
  def main(args: Array[String]) {
    val baos = new ByteArrayOutputStream()
    val oos = new ObjectOutputStream(baos)
    oos.writeObject(MyEnum.One)
    oos.close()
    val data = baos.toByteArray()
    println("size = " + data.length)
    val ois = new ObjectInputStream(new ByteArrayInputStream(data))
    val o = ois.readObject()

    println(MyEnum.One eq o)
  }
}

だと、falseと表示されるし、サイズが、1041バイトもあった。そりゃエンクロージングクラスのインスタンスまで直列化しているからなぁ。Enumerationのソースを見ると、

  protected class Val(i: Int, name: String) extends Value {
...
private def readResolve(): AnyRef =
if (values ne null) values(i)
else this
}

なるほど。valuesがnullだから、新しくインスタンス生成されてしまうわけだ。でもまぁ、Scalaの場合、==は、equals呼び出しになるから、直列化復元で別のオブジェクトになってしまっても、値が一緒ならいいのかもしれない。メモリ節約にこだわるなら、

object MyEnum extends Enumeration {
protected class Val(name: String) extends super.Val {
private def readResolve(): AnyRef = MyEnum.apply(id)
}

val One = new Val("One")
val Two = new Val("Two")
}

なら、うまくいった。う〜む、しかしEnum一個直列化して1k byteでは、ちょっとなぁ。エンクロージングクラスの名前を取る方法があれば、なんとかできそうな気がするけど、この手のsyntheticフィールド名は実装依存だし、APIにも取得用のメソッドは存在しない。無理だろうか。

このサイトの掲載内容は私自身の見解であり、必ずしもIBMの立場、戦略、意見を代表するものではありません。
日本アイ・ビー・エム 花井 志生 Since 1997.6.8


jpg4.us