疯狂Java学习笔记(56)------------对象序列化
疯狂Java学习笔记(56)------------对象序列化
1.需要将对象的状态保存到文件中(存储),而后能够通过读入对象状态来重新构造对象,恢复程序状态
2.使用套接字在网络上传送对象的程序来说,是很有用的(传输)。
我们通过让类实现java.io.Serializable 接口可以将类序列化。这个接口是一个制造者(marker)接口。也就是说,对于要实现它的类来说,该接口不需要实现任何方法。它主要用来通知Java虚拟机(JVM),需要将一个对象序列化。
对于这个,有几点我们需要明确:
1.并非所有类都可以序列化,在cmd下,我们输入serialver java.net.socket,可以得到socket是否可序列化的信息,实际上socket是不可序列化的。
2.java有很多基础类已经实现了serializable接口,比如string,vector等。但是比如hashtable就没有实现serializable接口。
将对象读出或者写入流的主要类有两个: ObjectOutputStream与ObjectInputStream 。
java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。
只有实现了Serializable和Externalizable接口的类的对象才能被序列化。Externalizable接口继承自 Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以 采用默认的序列化方式 。
对象序列化包括如下步骤:
1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
2) 通过对象输出流的writeObject()方法写对象。
对象反序列化的步骤如下:
1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
2) 通过对象输入流的readObject()方法读取对象。
对象序列化和反序列范例:
定义一个Person类,实现Serializable接口
-
[java] view plain copy
-
<span style="font-size:18px;">import java.io.Serializable;
-
-
/**
-
* <p>ClassName: Person<p>
-
* <p>Description:测试对象序列化和反序列化<p>
-
* @author xudp
-
* @version 1.0 V
-
* @createTime 2014-6-9 下午02:33:25
-
*/
-
public class Person implements Serializable {
-
-
/**
-
* 序列化ID
-
*/
-
private static final long serialVersionUID = -5809782578272943999L;
-
private int age;
-
private String name;
-
private String sex;
-
-
public int getAge() {
-
return age;
-
}
-
-
public String getName() {
-
return name;
-
}
-
-
public String getSex() {
-
return sex;
-
}
-
-
public void setAge(int age) {
-
this.age = age;
-
}
-
-
public void setName(String name) {
-
this.name = name;
-
}
-
-
public void setSex(String sex) {
-
this.sex = sex;
-
}
-
}</span>
序列化和反序列化Person类对象
-
<span style="font-size:18px;">import java.io.File;
-
import java.io.FileInputStream;
-
import java.io.FileNotFoundException;
-
import java.io.FileOutputStream;
-
import java.io.IOException;
-
import java.io.ObjectInputStream;
-
import java.io.ObjectOutputStream;
-
import java.text.MessageFormat;
-
-
/**
-
* <p>ClassName: TestObjSerializeAndDeserialize<p>
-
* <p>Description: 测试对象的序列化和反序列<p>
-
* @author xudp
-
* @version 1.0 V
-
* @createTime 2014-6-9 下午03:17:25
-
*/
-
public class TestObjSerializeAndDeserialize {
-
-
public static void main(String[] args) throws Exception {
-
SerializePerson();//序列化Person对象
-
Person p = DeserializePerson();//反序列Perons对象
-
System.out.println(MessageFormat.format("name={0},age={1},sex={2}",
-
p.getName(), p.getAge(), p.getSex()));
-
}
-
-
/**
-
* MethodName: SerializePerson
-
* Description: 序列化Person对象
-
* @author xudp
-
* @throws FileNotFoundException
-
* @throws IOException
-
*/
-
private static void SerializePerson() throws FileNotFoundException,
-
IOException {
-
Person person = new Person();
-
person.setName("gacl");
-
person.setAge(25);
-
person.setSex("男");
-
// ObjectOutputStream 对象输出流,将Person对象存储到E盘的Person.txt文件中,完成对Person对象的序列化操作
-
ObjectOutputStream oo = new ObjectOutputStream(new FileOutputStream(
-
new File("E:/Person.txt")));
-
oo.writeObject(person);
-
System.out.println("Person对象序列化成功!");
-
oo.close();
-
}
-
-
/**
-
* MethodName: DeserializePerson
-
* Description: 反序列Perons对象
-
* @author xudp
-
* @return
-
* @throws Exception
-
* @throws IOException
-
*/
-
private static Person DeserializePerson() throws Exception, IOException {
-
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
-
new File("E:/Person.txt")));
-
Person person = (Person) ois.readObject();
-
System.out.println("Person对象反序列化成功!");
-
return person;
-
}
-
-
}</span>
serialVersionUID的作用
简单来说,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)
举个实际应用的例子:
为了实现系统交互的目的,我们需要系统之间通过网络传输对象的实体(这些对象一般都是包括了系统中的一些数据)
Java序列化是一种解决方案:
系统A和B之间要进行交互,则A中的对象a首先会序列化,然后通过网络传输到系统B,在B中经反序列化还原,然后对其进行操作,利用对象a所提供的数据。
但要实现这种方案对原来的系统有如下的要求:
交互的系统之间要存在完全一致的对象模型,这就需要对原来的系统进行比较大的改变,不符合我们的要求。
因为序列化传输的数据是二进制格式的,除非把这些二进制的数据反序列化为对象,否则我们根本不能对其数据进行处理,也不能看到里面包含的数据是什么。
要求交互的系统都是基于Java的,因为Java序列化只能应用与Java系统之中。
Serializable的作用
为什么一个类实现了Serializable接口,它就可以被序列化呢?在上节的示例中,使用ObjectOutputStream来持久化对象,在该类中有如下代码:
文章来源: brucelong.blog.csdn.net,作者:Bruce小鬼,版权归原作者所有,如需转载,请联系作者。
原文链接:brucelong.blog.csdn.net/article/details/79989413
- 点赞
- 收藏
- 关注作者
评论(0)