Java序列化与反序列化
来源:互联网 发布:react js 中文教程 编辑:程序博客网 时间:2024/05/17 06:22
Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?本文围绕这些问题进行了探讨。
1.Java序列化与反序列化
Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。
2.为什么需要序列化与反序列化
我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的。如何做到呢?这就需要Java序列化与反序列化了。换句话说,一方面,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。
当我们明晰了为什么需要Java序列化和反序列化后,我们很自然地会想Java序列化的好处。其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),二是,利用序列化实现远程通信,即在网络上传送对象的字节序列。
3.如何实现Java序列化与反序列化
1)JDK类库中序列化API
java.io.ObjectOutputStream:表示对象输出流
它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
java.io.ObjectInputStream:表示对象输入流
它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回。
2)实现序列化的要求
只有实现了Serializable或Externalizable接口的类的对象才能被序列化,否则抛出异常。
3)实现Java对象序列化与反序列化的方法
假定一个Student类,它的对象需要序列化,可以有如下三种方法:
方法一:若Student类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化
ObjectOutputStream采用默认的序列化方式,对Student对象的非transient的实例变量进行序列化。
ObjcetInputStream采用默认的反序列化方式,对对Student对象的非transient的实例变量进行反序列化。
方法二:若Student类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。
ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。
ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化。
方法三:若Student类实现了Externalnalizable接口,且Student类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。
ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化。
ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化。
4)JDK类库中序列化的步骤
步骤一:创建一个对象输出流,它可以包装一个其它类型的目标输出流,如文件输出流:
ObjectOutputStream out = new ObjectOutputStream(new fileOutputStream(“D:\objectfile.obj”));
步骤二:通过对象输出流的writeObject()方法写对象:
out.writeObject(“Hello”);
out.writeObject(new Date());
5)JDK类库中反序列化的步骤
步骤一:创建一个对象输入流,它可以包装一个其它类型输入流,如文件输入流:
ObjectInputStream in = new ObjectInputStream(new fileInputStream(“D:\objectfile.obj”));
步骤二:通过对象输出流的readObject()方法读取对象:
String obj1 = (String)in.readObject();
Date obj2 = (Date)in.readObject();
import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;class Student implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private String name; private int age; private String sex; public Student() { } public Student(String name, int age, String sex) { super(); this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", sex=" + sex + "]"; }}public class SerializableTest { public static void main(String[] args) throws Exception { File file =new File("E:\\java\\file.txt"); if(!file.exists()) { file.createNewFile(); } FileOutputStream fileOut=new FileOutputStream(file); ObjectOutputStream objOut=new ObjectOutputStream(fileOut); objOut.writeObject(new Student("叫相遇", 22, "男")); objOut.writeObject(new Student("叫相遇2", 22, "男2")); for(int i=1;i<10;i++) { objOut.writeObject(new Student("叫相遇"+i, 22, "男")); } FileInputStream fileIn=new FileInputStream(file); ObjectInputStream objIn=new ObjectInputStream(fileIn); System.out.println(objIn.readObject()); System.out.println(objIn.readObject()); }}
总结:writeObject(Object obj)用把对象序列化以二进制形式存到文本文件会是乱码,但并不影响用readObject()反序化读写;还有一点是,用writeObject(Object obj)写入文本数据不会换行,这点不太好,序列化和反序列化是为了进程自己通信、网络上传送、存到磁盘持久化,但这个存到文本文件不是给用户用肉眼看的,这些数据只有计算机可读懂。如果想要用肉眼看懂文本文件内容就不建议用这种方式了。
- java序列化与反序列化
- java序列化与反序列化
- java序列化与反序列化
- java序列化与反序列化
- Java序列化与反序列化
- Java序列化与反序列化
- java 序列化 与 反序列化
- java序列化与反序列化
- JAVA序列化与反序列化
- java序列化与反序列化
- java序列化与反序列化
- java序列化与反序列化
- Java序列化与反序列化
- Java序列化与反序列化
- Java序列化与反序列化
- Java序列化与反序列化
- Java序列化与反序列化
- java序列化与反序列化
- Operator Of C++
- php一个生成唯一订单的函数
- ftp虚拟帐号的建立及相关使用
- ACdream1066
- JZOJ5463. 【NOIP2017提高A组冲刺11.8】证书
- Java序列化与反序列化
- JAVA基础复习十八-Map集合、Collections类
- mac下lua调用c生成的so文件
- vector用法
- 常用排序算法的Python实现
- RecyclerView 瀑布流显示图片
- maven项目的依赖管理
- MyBatis Generator 常用配置记录说明
- FFmpeg安装(windows环境)