Java序列化问题,同时使用guava Lists.transform

unc*_*ons 6 java serialization guava

我不得不序列化一个复杂的对象,但其中一个组件是不可序列化的(第三方图形对象),所以我创建了这个Graph类的自定义可序列化版本,并使用Guava List转换将非可序列化对象转换为自定义对象.序列化writeObject仍然失败.我有兴趣知道为什么吗?我的假设是Lists.transform执行Lazily操作(保持对原始对象的隐藏引用.)

还有解决这个问题的方法吗?

Pau*_*ing 13

你怀疑Lists.transform()确实懒散地执行.你可以做其中一个

Lists.newArrayList(Lists.transform(...))
Run Code Online (Sandbox Code Playgroud)

或者,如果你想要一个不可变的版本,

ImmutableList.copyOf(Lists.transform(...))
Run Code Online (Sandbox Code Playgroud)

然后序列化结果列表.

  • OP声明fromList特别充满了不可序列化的元素. (2认同)

Eti*_*veu 7

Lists.transform()返回原始列表的变换视图.来自Lists.transform()javadoc:

返回的列表始终实现Serializable,但只有当fromList和function可序列化时,序列化才会成功.

序列化转换后的视图时,实际上是序列化原始列表和函数.在您的情况下,它失败,因为您的原始列表不可序列化(因为它包含不可序列化的图形元素).但它也可能失败,因为该函数不实现可序列化.

顺便说一下,有一个小技巧来创建可序列化的功能而没有冗长.而不是做:

  private static final class MyFunction extends Function<String, String> implements Serializable {
    private static final MyFunction INSTANCE = new MyFunction();

    @Override
    public String apply(String input) {
      return "[" + input + "]";
    }

    private Object readResolve() {
      return INSTANCE;
    }
    private static final long serialVersionUID = 1;
  }
Run Code Online (Sandbox Code Playgroud)

你可以使用enum singleton模式,它不那么详细,并且免费获得序列化(因为枚举是可序列化的).它还确保您的Function是一个单例:

  // enum singleton pattern
  private enum MyFunction implements Function<String, String> {
    INSTANCE;

    @Override
    public String apply(String input) {
      return "[" + input + "]";
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • 真棒......有效的Java.谢谢. (2认同)