序列化和反序列化

1. Java序列化和反序列化

Java序列化是指将Java对象转化为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。 当两个进程进行远程通信时,这个通信的数据可以为文本、图片、音频或者视频等,而这些数据都是以二进制的形式进行传送的。而当两个Java进程间进行通信时,进程间对象的传送也是二进制方式传输。这就要用到序列化和反序列化,一方面,发送方需要把这个Java对象转化为字节序列,另一方面接收方要从字节序列中恢复出Java对象。

好处:
* 实现了数据的持久化,通过序列化可以把数据永久地存放在硬盘上
* 利用反序列化实现远程通信,即在网络上传送对象的字节序列化

2. 如何实现Java序列化和反序列化

2.1 JDK类库中序列化API
- java.io.ObjectOutputStream:表示对象输出流
它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
-java.io.ObjectInputStream:表示对象输入流-
它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回。
- 序列化步骤:
步骤一:创建一个对象输出流,它可以包装一个其它类型的目标输出流,如文件输出流:
ObjectOutputStream out = new ObjectOutputStream(new fileOutputStream(“D:\objectfile.obj”));
步骤二:通过对象输出流的writeObject()方法写对象:
out.writeObject(“Hello”);
out.writeObject(new Date());
- 反序列化步骤:
步骤一:创建一个对象输入流,它可以包装一个其它类型输入流,如文件输入流:
ObjectInputStream in = new ObjectInputStream(new fileInputStream(“D:\objectfile.obj”));
步骤二:通过对象输出流的readObject()方法读取对象:
String obj1 = (String)in.readObject();
Date obj2 = (Date)in.readObject();

2.2 实现序列化接口
只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以 采用默认的序列化方式 。

2.3 案例

import java.io.Serializable;  
public class Student implements Serializable  
{  
     private static final long serialVersionUID = 4603642343377807741L;
     private String name;  
     private char sex;  
     private int year;  
     private double gpa;  

     public Student()  
     {  

     }  
     public Student(String name,char sex,int year,double gpa)  
     {  
          this.name = name;  
          this.sex = sex;  
          this.year = year;  
          this.gpa = gpa;  
     }  

     public void setName(String name)  
     {  
         this.name = name;  
     }  

     public void setSex(char sex)  
     {  
        this.sex = sex;  
     }  

     public void setYear(int year)  
     {  
         this.year = year;  
     }  

     public void setGpa(double gpa)  
     {  
         this.gpa = gpa;  
     }  

     public String getName()  
     {  
         return this.name;  
     }  
     public char getSex()  
     {  
        return this.sex;  
     }  
     public int getYear()  
     {  
        return this.year;  
     }  
     public double getGpa()  
     {  
        return this.gpa;  
     }  
}  

把Student类的对象序列化到文件D:\student.txt,并从该文件中反序列化,向console显示结果。代码如下:

import java.io.*;  
public class UseStudent  
{  
     public static void main(String[] args)  
     {  
          Student st = new Student("Tom",'M',20,3.6);  
          File file = new File("D:\\student.txt");  
          try  
          {  
                file.createNewFile();  
          }  
          catch(IOException e)  
          {  
                e.printStackTrace();  
          }  
          try  
          {  
               //Student对象序列化过程  
               FileOutputStream fos = new FileOutputStream(file);  
               ObjectOutputStream oos = new ObjectOutputStream(fos);  
               oos.writeObject(st);  
               oos.flush();  
               oos.close();  
               fos.close();  

               //Student对象反序列化过程  
               FileInputStream fis = new FileInputStream(file);  
               ObjectInputStream ois = new ObjectInputStream(fis);  
               Student st1 = (Student) ois.readObject();  
               System.out.println("name = " + st1.getName());  
               System.out.println("sex = " + st1.getSex());  
               System.out.println("year = " + st1.getYear());  
               System.out.println("gpa = " + st1.getGpa());  
               ois.close();  
               fis.close();  
          }  
          catch(ClassNotFoundException e)  
          {  
                e.printStackTrace();  
          }  
          catch (IOException e)  
          {  
                e.printStackTrace();  
          }               
     }  
}  

3.serialVersionUID的作用
serialVersionUID字面意思是序列化版本号,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量。Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)
serialVersionUID的作用生成方式:
1.一个是默认的1L,比如:private static final long serialVersionUID = 1L;
2.一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段
++ 为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。 ++

参考博客:
http://kb.cnblogs.com/page/515982/
http://blog.csdn.net/abc6368765/article/details/51365838
http://blog.csdn.net/wangloveall/article/details/7992448/
http://kb.cnblogs.com/page/515982/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值