码迷,mamicode.com
首页 > 其他好文 > 详细

对象的序列化和反序列化

时间:2020-10-12 20:35:32      阅读:25      评论:0      收藏:0      [点我收藏+]

标签:也会   反序   val   his   属性   setname   flush   传输   rgb   

1.序列化定义

  将内存中的java对象放到硬盘文件中(将对象切成一块块的、按序列顺序传输

2.反序列化

  将硬盘文件中的java对象放到内存中(将对象切成一块块的、按序列顺序传输)

 

                                                        技术图片

 3.单个对象的序列化及反序列化

序列化

首先,新建一个类,实现Serializable接口

 1 package bean;
 2 
 3 import java.io.Serializable;
 4 //参与序列化的类必须实现Serializable接口,否则会报错
 5 //Serializable只是一个标志接口,接口中什么代码也没有,起到一个标志的作用,java虚拟机看到这个类实现了这个接口,所以会对这个类给予特殊待遇
 6 //Serializable这个标志接口是给java虚拟机参考的,java虚拟机看到这个接口后,会为该类自动生成一个序列化版本号
 7 //序列化版本号的用处:
 8 public class Student implements Serializable  {
 9     
10     private int no;
11     private String name;
12     
13     public Student(int no, String name) {
14         super();
15         this.no = no;
16         this.name = name;
17     }
18     public int getNo() {
19         return no;
20     }
21     public void setNo(int no) {
22         this.no = no;
23     }
24     public String getName() {
25         return name;
26     }
27     public void setName(String name) {
28         this.name = name;
29     }
30     @Override
31     public String toString() {
32         return "Student [no=" + no + ", name=" + name + "]";
33     }
34     
35 
36 }

接下来,进行序列化操作

 1 package IoTest;
 2 
 3 import java.io.FileNotFoundException;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 import java.io.ObjectOutputStream;
 7 
 8 import bean.Student;
 9 
10 public class ObjectOutputStreamTest {
11     
12     
13     public static void main(String[] args) throws FileNotFoundException, IOException{
14         //创建java对象
15         Student s=new Student(111,"张三");
16         
17         //序列化
18         ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("students"));
19         
20         //序列化对象
21         oos.writeObject(s);
22         
23         oos.flush();
24         oos.close();
25     }
26 
27 }

运行结果:

技术图片

 

 

 

反序列化

 1 package IoTest;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileNotFoundException;
 5 import java.io.IOException;
 6 import java.io.ObjectInputStream;
 7 
 8 public class ObjectInputStreamTest {
 9     //反序列化
10     public static void main(String[] args) throws Exception{
11         
12             ObjectInputStream oii=new ObjectInputStream(new FileInputStream("students"));
13             
14             //开始反序列化,读
15             Object obj=oii.readObject();
16             //反序列化回来是一个学生对象,所以会调用学生对象的toString方法。
17             System.out.println(obj);
18             
19             oii.close();
20     }
21 
22 }

运行结果:

技术图片

 

 4.多个对象序列化及反序列化

序列化

 1 package IoTest;
 2 
 3 import java.io.FileNotFoundException;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 import java.io.ObjectOutputStream;
 7 import java.util.ArrayList;
 8 import java.util.List;
 9 
10 //一次序列化多个对象:可以将对象放到序列化集合中
11 public class ObjectOutputStreamTest1 {
12     
13     public static void main(String[] args) throws Exception{
14         List<User> userList=new ArrayList<>();
15         userList.add(new User(1,"张大狗"));
16         userList.add(new User(2,"刘二狗"));
17         userList.add(new User(1,"钱小狗"));
18         ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("users"));
19         oos.writeObject(userList);
20         oos.flush();
21         oos.close();
22         System.out.println("完成");
23     }
24     
25 
26 }

运行结果:

技术图片

 

 

反序列化

 1 package IoTest;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileNotFoundException;
 5 import java.io.IOException;
 6 import java.io.ObjectInputStream;
 7 import java.util.List;
 8 
 9 //反序列化集合
10 public class ObjectInputStreamTest1 {
11     
12     public static void main(String[] args) throws Exception{
13         
14         ObjectInputStream oii=new ObjectInputStream(new FileInputStream("users"));
15         List<User>userList=(List<User>)oii.readObject();
16         for(User user:userList){
17             System.out.println(user.toString());
18         }
19         oii.close();
20         
21     }
22 
23 }

运行结果:

技术图片

 

 5.若不想使某个属性参与序列化,则可以使用transient关键字

private transient String name;  //若不想使某个属性参与序列化,则可以使用transient关键字

经过序列化--->反序列化操纵后,运行结果为:

 技术图片

 

 6.

//过了很久,Student这个类源代码改动了。
    //源代码改动之后,需要重新编译,编译之后生成了全新的字节码文件
    //并且class文件再次运行的时候,java虚拟机生成的序列化版本号也会发生相应的改变
    private int st_age;

反序列化后结果:

技术图片

 

 

 

 

序列化版本号不一致
Exception in thread "main" java.io.InvalidClassException: bean.Student; local class incompatible: 
stream classdesc serialVersionUID = -7370765433862913044(很久之前的序列化版本号)
local class serialVersionUID = -5935280165290247344(现在的序列化版本号)

序列化版本号的作用:
    java中是采用什么机制来区分类的?
    第一:首先通过类名进行比较,如果类名不一样,肯定不是同一个类。
    第二:如果类名一样,则是通过序列化版本号进行区分的。

    A编写了一个类:com.java.bean.Student implements Serializable
    B编写了一个类:com.java.bean.Student implements Serializable
    不用的人编写了同一个类,但是“这两个类确实不是同一个类”,这个时候就需要序列化版本号起作用了。对于java虚拟机来说,java虚拟机是可以区分开这两个类的,因为这两个类都实现了Serializable接口,都有默认的序列化版本号,它们的序列化版本号不一样,所以区分开了。这是自动生成序列化版本号的好处。

    思考:自动生成序列化版本号的缺陷?

 

对象的序列化和反序列化

标签:也会   反序   val   his   属性   setname   flush   传输   rgb   

原文地址:https://www.cnblogs.com/Leeyoung888/p/13803507.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!