首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >java defaultWriteObject方法与writeObject方法的异同

java defaultWriteObject方法与writeObject方法的异同
EN

Stack Overflow用户
提问于 2018-08-22 06:24:21
回答 1查看 560关注 0票数 1

我正在尝试理解java序列化机制,而且我没有什么疑问

请回答以下有关java序列化的问题:

  • 我们为什么要使用oos.defaultWriteObject();?根据this post,its在那里是为了向后兼容性。我也不太明白它是如何实现不兼容更改的that.one的,因为序列化是删除更新版本中的字段。这意味着旧版本必须设置默认值(有时对user.how无效),这与添加新字段并允许设置默认值的新版本有什么不同吗?
  • 在自定义序列化过程中,使用oos.defaultWriteObject();oos.writeObject(address);会有什么不同吗?我的意思是将所有超类和当前类的非瞬态非静态字段写入OOS。

这里

代码语言:javascript
运行
复制
private void writeObject(java.io.ObjectOutputStream stream)
        throws IOException {
    stream.writeObject(name);
    stream.writeInt(id);
    stream.writeObject(DOB);
}

private void readObject(java.io.ObjectInputStream stream)
        throws IOException, ClassNotFoundException {
    name = (String) stream.readObject();
    id = stream.readInt();
    DOB = (String) stream.readObject();
}

以上代码产生的结果与下面的代码相同

代码语言:javascript
运行
复制
private void writeObject(java.io.ObjectOutputStream stream)
            throws IOException {
        stream.defaultWriteObject();
    }

    private void readObject(java.io.ObjectInputStream stream)
            throws IOException, ClassNotFoundException {
         stream.defaultReadObject();
    }

何时使用这两个方法,何时只使用writeObject(employee);//employee是我的整个对象//

  1. 以下是不回答我问题的可能重复的问题清单。
  2. 它说*如果在编写可选数据之前没有调用一次question 1或writeFields (如果有的话),那么在ObjectInputStream*但是我仍然可以不使用deafultwriteobject.right调用writeObject的情况下,实例反序列化的行为是没有定义的?
  3. question 2这些答案说,defaultwriteobject方法会将一些额外的数据写入流,并且它会反思广益地检查要写什么。oos.writeobject(object obj)也会反射检查吗?
  4. 最后,我可以通过重写writeObject和ReadObject方法来控制我的序列化,那么Externalizable的意义是什么?
  5. 如果提供串行versionUID不引发异常,那么如果反序列化具有该字段的旧类中缺少字段的对象,那么如果提供自己的SerialverUID,所有不兼容的更改基本上会发生什么呢?它是否有自己的串行版本,UID不会为所有兼容的更改抛出流损坏的异常?
EN

回答 1

Stack Overflow用户

发布于 2019-12-25 10:12:16

请回答你的问题

  1. writeObject并不是为了向后兼容性。readObject是。
  2. 他们是一样的。defaultWriteObject帮助您快速编写“可序列化”值。

后向兼容性

假设您的bean添加了一个新字段。

代码语言:javascript
运行
复制
class Bean implements Serializable {
  int id;
  String name;
  String newValue = "123";
}

尽管您已经给出了newValue默认值,但是java序列化将忽略它。(因为它分配实例而不是new )

现在,如果您不使用readObject,您将得到newValue=null。因此,您也需要在readObject进行初始化。

代码语言:javascript
运行
复制
  private void readObject(ObjectInputStream stream) throws Exception {
    stream.defaultReadObject();
    this.newValue = "123";
  }

defaultWriteObject如何帮助你

考虑到除了某些字段之外,bean几乎是“可序列化的”。

请参见下面的代码。BadThing不是Serializable,或者它有一些您不想序列化的敏感数据。

代码语言:javascript
运行
复制
class Bean implements Serializable {
  int id;
  String string;
  BadThing badThing;
}

要快速序列化它,可以让字段transient并编写writeObject方法来处理它。

代码语言:javascript
运行
复制
  private void writeObject(ObjectOutputStream stream) throws Exception {
    stream.defaultWriteObject();
    stream.writeInt(badThing.id);
  }

  // Corresponding `readObject`

当然,您可以将defaultWriteObject替换为几个writeXXX。但是如果您有很多字段,那么编写代码是很累的,很无聊,对吧?

因此,defaultWriteObject只是为了避免编写无聊的代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51960890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档