java序列化与反序列化

比眉伴天荒 2022-05-29 12:13 478阅读 0赞

**序列化和反序列化的概念
把对象转化为字节序列的过程称之为对象的序列化
反之,称之为反序列化

serialVersionUID的作用
如果没有为指定的class配置serialVersionUID,那么java编译器会自动给这个class进行一个摘要算法,类似于指纹算法,只要这个文件有任何改动,得到的UID就会截然不同的,可以保证在这么多类中,这个编号是唯一的。所以,由于没有显指定 serialVersionUID,编译器又为我们生成了一个UID,当然和前面保存在文件中的那个不会一样了,于是就出现了2个序列化版本号不一致的错误。因此,只要我们自己指定了serialVersionUID,就可以在序列化后,去添加一个字段,或者方法,而不会影响到后期的还原,还原后的对象照样可以使用,而且还多了方法或者属性可以用。

静态变量的序列化
序列化并不保存静态变量的状态

Transient关键字
transient关键字表示指定属性不参与序列化

父子类问题
如果父类没有实现序列化,而子类实现列序列化。那么父类中的成员没办法做序列化操作

序列化的存储规则
对同一个对象进行多次写入,打印出的第一次存储结果和第二次存储结果,只多了5个字节的引用关系。
并不会导致文件累加

序列化实现深度克隆
浅拷贝(浅复制、浅克隆):被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅拷贝仅仅复制所拷贝的对象,而不复制它所引用的对象。

深拷贝(深复制、深克隆):被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深拷贝把要复制的对象所引用的对象都复制了一遍

下面是将一个对象进行序列化和反序列化的例子:

  1. public class Person implements Serializable{
  2. private static final long serialVersionUID = -2572627257192440740L;
  3. private String name;
  4. private int age;
  5. public String getName() {
  6. return name;
  7. }
  8. public void setName(String name) {
  9. this.name = name;
  10. }
  11. public int getAge() {
  12. return age;
  13. }
  14. public void setAge(int age) {
  15. this.age = age;
  16. }
  17. }
  18. public class SerializeDemo {
  19. public static void main(String[] args) {
  20. // 序列化操作
  21. SerializePerson();
  22. //反序列化操作
  23. Person person=DeSerializePerson();
  24. System.out.println(person);
  25. }
  26. private static void SerializePerson(){
  27. try {
  28. ObjectOutputStream oo=new ObjectOutputStream(new FileOutputStream(new File("person")));
  29. Person person=new Person();
  30. person.setAge(18);
  31. person.setName("test");
  32. oo.writeObject(person);
  33. oo.flush();
  34. System.out.println("序列化成功: "+new File("person").length());
  35. oo.close();
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. } catch (ClassNotFoundException e) {
  39. e.printStackTrace();
  40. }
  41. }
  42. private static Person DeSerializePerson(){
  43. ObjectInputStream ois= null;
  44. try {
  45. ois = new ObjectInputStream(new FileInputStream(new File("person")));
  46. Person person=(Person)ois.readObject();
  47. return person;
  48. } catch (IOException e) {
  49. e.printStackTrace();
  50. } catch (ClassNotFoundException e) {
  51. e.printStackTrace();
  52. }
  53. return null;
  54. }
  55. }

总结
1.在java中,只要一个类实现了java.io.Serializable接口,那么它就可以被序列化
2.通过ObjectOutputStream和ObjectInputStream对对象进行序列化合反序列化操作

  1. 对象是否允许被反序列化,不仅仅是取决于对象的代码是否一致,同时还有一个重要的因素(UID)
  2. 序列化不保存静态变量
  3. 要想父类对象也参与序列化操作,那么必须要让父类也实现Serializable接口
  4. Transient关键字,主要是控制变量是否能够被序列化。如果没有被序列化的成员变量反序列化后,会被设置成初始值,比如String -> null
  5. 通过序列化操作实现深度克隆

发表评论

表情:
评论列表 (有 0 条评论,478人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java序列序列

    序列化:java对象转化为字节序列,反序列化:字节序列转化为java对象 好处:其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),

    相关 Java序列序列

    Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?本文围绕这些问题进行了探讨。  1.Java序列化与反序列化  Java序列化

    相关 Java序列序列

    基本概念: 序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。 昨天在一

    相关 java 序列序列

    一、什么是序列化与反序列化? > Java 序列化是指把 Java 对象转换为字节序列的过程; > Java 反序列化是指把字节序列恢复为 Java 对象的过程; 二、