AI智能
改变未来

java进阶(35)–对象流、序列化与反序列化

文档目录:

一、基础概念

二、举例-序列化对象

三、举例-反序列化对象

四、举例-序列化与反序列化多个对象与

五、transient关键字

六、序列化版本号

—————————————分割线:正文——————————————————–

一、基础概念

1、序列化:

关键词为Serialize,Java对象的状态保存下来的过程

2、反序列化:

关键词为DeSerialize,将硬件上的数据重新恢复到内存当中,恢复成Java对象

3、Serializable接口

参与序列化与反序列化的对象必须实现Serializable接口

参与序列化的集合元素都要实现Serializable接口,Serializable为一种标志接口

4、序列化版本号

Serializable是给Java虚拟机看的,会加载该类自动生成一个序列化版本号

二、举例-序列化对象

1、创建实现Serializable的student类

1 package JAVAADVANCE;2 import java.io.Serializable;3 public class Student02 implements Serializable {4     private int no;5     private String name;6     public Student02() {7     }8     public Student02(int no, String name) {9         this.no = no;10         this.name = name;11     }12     public int getNo() {13         returnad8no;14     }15     public void setNo(int no) {16         this.no = no;17     }18     public String getName() {19         return name;20     }21     public void setName(String name) {22         this.name = name;23     }24 }

2、创建TestAdvance35TestObjectOutputStreamTest01类实现序列化对象

1 package JAVAADVANCE;2 import java.io.FileOutputStream;3 import java.io.IOException;4 import java.io.ObjectOutputStream;5 public class TestAdvance35Tead0stObjectOutputStreamTest01 {6     public static void main(String[] args) throws IOException {7         //创建java对象8         Student02 s=new Student02(1111,\"zhangsan\");9         //创建流10         ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(\"students\"));11         //序列化java对象12         oos.writeObject(s);13         //刷新14         oos.flush();15         //关闭16         oos.close();17     }1819 }

项目文件目录下生成Students文件,存储java对象,无法直接读取,需要反序列化读取

三、举例-反序列化对象

1 packagead8JAVAADVANCE;2 import java.io.*;3 public class TestAdvance35TestObjectInputStreamTest01 {4     public static void main(String[] args) throws IOException, ClassNotFoundException {5         //创建流6         ObjectInputStream ois=new ObjectInputStream(new FileInputStream(\"students\"));7         //开始反序列化8         Object obj=ois.readObject();9         //反序列化回来的是一个student02对象,所有会调用student02对象的toString方法10         System.out.println(obj);11         ois.close();12     }13 }

查看运行结果:

Student02{no=1111, name=\’zhangsan\’}

四、举例-序列化与反序列化多个对象

1、创建User类实现Serializable接口

1 import java.io.Serializable;23 public class User implements Serializable {4     private String name;5     private int no;67     public User() {8     }910     public User(String name, int no) {11         this.name = name;12         this.no = no;13     }1415     @Override16     public String toString() {17         return \"User{\" +18                 \"name=\'\" + name + \'\\\'\' +19                 \", no=\" + no +20                 \'}\';21     }22 }

2、序列化多个对象

1 package JAVAADVANCE;23 import java.io.FileOutputStream;4 import java.io.IOException;5 import java.io.ObjectOutputStream;6 import java.util.ArrayList;7 import java.util.List;89 public class TestAdvance35TestObjectOutputStreamTest02 {10     public static void main(String[] args) throws IOException {11         List<User> userList =new ArrayList<>();12         userList.add(new User(1,\"zhangsan\"));13         userList.add(new User(2,\"lisi\"));14         userList.add(new User(3,\"wanglu\"));15         ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(\"user\"));16         oos.writeObject(userList);17         oos.flush();18         oos.close();19     }2021 }

3、反序列化多个对象

1 package JAVAADVANCE;23 import java.io.FileInputStream;4 import java.io.IOException;5 import java.io.ObjectInputStream;6 import java.util.List;78 public class TestAdvance35TestObjectInputStreamTest02 {9     public static void main(String[] args) throws IOException, ClassNotFoundException {10         ObjectInputStream ois=new ObjectInputStream(new FileInputStream(\"user\"));11 //        Object obj=ois.readObject();12 //        System.out.println(obj instanceof List);//返回true13         List<User> userList=(List<User>)ois.readObject();14         for(User user:userList){15             System.out.println(user);16         }17         ois.close();18     }19 }

4、查看执行结果:

User{name=\’zhangsan\’, no=1}
User{name=\’lisi\’, no=2}
User{name=\’wanglu\’, no=3}

五、transient关键字

1、transient关键字

表示为游离的状态,如name加上transient代表name不参与序列化

2、举例说明

以上例子User类name加上transient

1 package JAVAADVANCE;2 import java.io.Serializable;3 public class User implements Serializable {4     private transient String name;5     private int no;6     public User() {7     }89     public User( int no,String name) {10         this.no = no;11         this.name = name;12     }1314     @Override15     public String toString() {16         return \"User{\" +17                 \"name=\'\" + name + \'\\\'\' +18                 \", no=\" + no +19                 \'}\';20     }21 }

3、查看结果:

再次执行反序列化

User{name=\’null\’, no=1}
User{nam56ce=\’null\’, no=2}
User{name=\’null\’, no=3}

六、序列化版本号

1、 背景:

当Student源代码发生改动后,需要重新编译,会生成新的字节码文件,class文件再次运行的时候,java虚拟机生成的序列化版本号也会发生相应改变。

到导致java.io.InvaildClassException;SerialVersionUID不一致的情况。

2、java语言中如何区分类:

如果类名不一样,不是同一个类;类名同样的情况下,靠序列化版本号进行区分

3、建议:

凡是类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号,java虚拟机会认为是同一个类

private static final long serialVersionUID=1L;

4、Idea快速生成序列化版本号

class类,alt+回车实现

需要设置:File-Setting-Editor-Inspections-搜索serializable-Serializable class without serialVersionUID-Apply

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » java进阶(35)–对象流、序列化与反序列化