GuavaのLists#transformが返すリストはシリアライズできないんだね
Androidアプリをジャバで書くならGuavaは、僕にとって必要不可欠なライブラリだ。
リストをmapする操作は頻出するパターンなのでLists#transform(List, Function)
メソッドがないと生きて行けない。
タイトルの通りなんだけど、このLists#transform
メソッドが返すリストはシリアライズできない。そのことを知らずにシリアライズしてみたらNotSerializableException
が出て悩んだのでメモ
。
Lists#transform
の引数のFunction
はすぐには適用されず必要なときまで遅延する。そのためLists#transform
が返すリスト(非公開の内部staticクラス)は、引数のFunction
を持っている。で、この非公開の内部staticなリストクラスはSerializableを実装している。ここまではいい。
問題はそのクラスの、非transient
なフィールドFunction
がSerializable
ではないこと。
それが原因でLists#transform
が返すリストはNotSerializableException
を吐いてシリアライズに失敗する。
これは...バグ?と思いissueを覗いてみたら同じことを思った人が投稿してた。
https://code.google.com/p/guava-libraries/issues/detail?id=1424
このissue、WorkingAsIntendedということでクローズしてて「ん!?」って一瞬思ったけど読んでみて納得した。
中の人曰く、直列化は実装上の問題だから抽象型をSerializableにするな(だからFunction
をSerializable
にしない)と。その他にもいろいろ言ってる。
ちなみにシリアライズできない旨がjavadocに明記されてた...。迷ったら、まずドキュメントを読もう...。
Lists#transform
が返すリストをシリアライズしたい場合はこうすりゃいい。
List<Foo> list = Lists.transform(fromList, function); serialize(ImmutableList.copyOf(list));
以上