序列化和反序列化

来源:互联网 发布:sqoop mysql导入hbase 编辑:程序博客网 时间:2024/06/08 13:53
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
原创粉丝点击