Java序列化是确定性的吗?

时间:2018-04-19 06:40:37

标签: java serialization deserialization

如果我有一个实现Serializable的类,例如:

public class Foo implements Serializable {
    public String a;
    public String b;
}

使用ObjectOutputStream序列化对象确定性吗?

2 个答案:

答案 0 :(得分:0)

我已经实现了示例代码。

 public class Foo implements Serializable {
   public String a;
  public String b;
}

在测试类中

public class Test{
  public static void main(String[] args){
    try{
     FileOutputStream fos=new FileOutputStream("saved_filename.dat");
     ObjectOutputStream oos=new ObjectOutputStream(fos);
     Foo f1=new Foo();
     oos.writeObject(f1);
    }catch(exception e){
      e.printStackTrace();
    }finally{
      if(fos!=null) try{fos.close();}catch{IOException e){}
      if(oos!=null) try{oos.close();}catch{IOException e){}
    }
   }
}

看起来像这样。

答案 1 :(得分:0)

Java序列化是确定性的,从某种意义上来说,一个对象在通过内置序列化机制进行序列化时通常总是产生相同的字节流。有一些警告:

  • 协议的版本不同,新的Java版本可能会添加新的协议版本。
  • Java在流中包括一个对象标识,以允许序列化任意对象图。该标识是单个流的本地标识,因此,如果将一个对象两次序列化为两个独立的流,则此标识号应该相同。但是,如果此身份是“对象”的一部分或某些对象标头的一部分,则取决于情况。
  • 可以定义自己的readObjectwriteObject方法,或者实现Externalizable接口来自己进行序列化。在这种情况下,确定性完全取决于您自己的代码是否具有确定性。

我也遇到了这个问题,因为Apache Beam / Dataflow告诉我我的序列化器不是确定性的。对于Beam,有一个不同的考虑:它有时要求序列化程序具有确定性,因为两个与其.equals()方法比较的对象也必须序列化到相同的字节流。 (可能是为了使框架可以根据字节流进行分组。)由于必须在Java中定义自己的equals方法,因此即使两个对象没有序列化为相同的字节,它们也可以自由比较两个对象流。例如,如果对象包括一些在进行相等性比较时未考虑的字段。因此,Beam认为Java序列化是不确定的。