<< 初めてのテレビゲーム | Home | [備忘録] Xftフォント一覧 >>
PR: 転職    お墓    エコ    通販    結婚相談所    シルバー    質屋    葬式    漫画    エステサロン   

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