疯狂Java学习笔记(56)------------对象序列化
来源:互联网 发布:windows mirai病毒 编辑:程序博客网 时间:2024/06/03 05:43
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接口
<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来持久化对象,在该类中有如下代码:
- 疯狂Java学习笔记(56)------------对象序列化
- 疯狂Java学习笔记(84)----------关于 Java 对象序列化您不知道的 5 件事
- Java学习笔记(56)------------对象序列化
- 疯狂Java之学习笔记(14)-----------类、对象
- 疯狂java学习笔记
- Java与Flex学习笔记(6)----Java对象与ActionScript对象之间的序列化
- 《疯狂JAVA讲义》学习笔记(一)
- 学习java疯狂讲义笔记(连载)
- 疯狂Java之学习笔记(前言)
- 疯狂Java学习笔记(50)-----------JDBC
- 疯狂Java学习笔记(68)-----------synchronized
- 疯狂Java学习笔记(69)---------Lock
- 疯狂Java学习笔记(71)----------volatile
- 疯狂Java学习笔记(73)-----------ThreadLocal
- 疯狂Java之学习笔记(4)---------------UML及面向对象
- [疯狂Java]I/O:I/O流的最高境界——对象流(序列化:手动序列化、自动序列化、引用序列化、版本)
- java学习笔记--字符流、对象序列化
- java 学习笔记11之对象序列化
- getAttribute()和getParameter()区别
- B\S备忘录16——tomcat压缩版安装
- Linux下套接字详解(一)----TCP/UDP的区别与联系
- 使用CNN(convolutional neural nets)检测脸部关键点教程(二):浅层网络训练和测试
- CLang之简单介绍
- 疯狂Java学习笔记(56)------------对象序列化
- [算法]Java实现 不断前移重复出现的元素 Move Element To Front
- LBSN中好友与用户活动的关系
- 跟我学Java反射——一步曲
- itop4412的linux环境搭建
- change between std::string & int demo
- 第十三周阅读项目(虚析构函数)
- Mongodb启动配置
- Codeforces Round #305 B题 思维+贪心