JAVA的序列化与反序列化
一、为什么要进行序列化
再介绍之前,我们有必要先了解下对象的生命周期,我们知道Java对象的生命周期,也即Java中的远程方法调用RMI也会被用到,在网络中要传输对象的话,则必须要对对象进行序列化,关于RMI有机会我会再专门开贴介绍。
简单总结起来,进行对象序列化的话的主要原因就是实现对象持久化和进行网络传输,这里先只介绍怎样通过对象序列化保存对象的状态。
下面我们通过一个简单的例子来介绍下如何进行对象序列化。
二、怎样进行对象序列化
假设我们要保存Person类的某三个对象的name、age、height这三个成员变量,当然这里只是简单举例
我们先看下Person类,要序列化某个类的对象的话,则该类必要实现Serializable接口,从中我们发现该接口是个空接口,即该接口中没声明任何方法。
import java.io.Serializable;
public class Person implements Serializable {
int age;
int height;
String name;
public Person(String name, int age, int height){
this.name = name;
this.age = age;
this.height = height;
}
}
下面我们看一下如何来进行序列化,这其中主要涉及到java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class MyTestSer {
/**
* 的序列化与反序列化
*/
public static void main(String[] args) {
Person zhangsan = new Person("zhangsan", 30, 170);
Person lisi = new Person("lisi", 35, 175);
Person wangwu = new Person("wangwu", 28, 178);
try {
//需要一个文件输出流和对象输出流;文件输出流用于将字节输出到文件,对象输出流用于将对象输出为字节
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("person.ser"));
out.writeObject(zhangsan);
out.writeObject(lisi);
out.writeObject(wangwu);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
三、对象的反序列化
我们存储的目的主要是为了再恢复使用,下面我们来看下加上反序列化后的代码:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
public class MyTestSer {
/**
* 的序列化与反序列化
*/
public static void main(String[] args) {
Person zhangsan = new Person("zhangsan", 30, 170);
Person lisi = new Person("lisi", 35, 175);
Person wangwu = new Person("wangwu", 28, 178);
try {
//需要一个文件输出流和对象输出流;文件输出流用于将字节输出到文件,对象输出流用于将对象输出为字节
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("person.ser"));
out.writeObject(zhangsan);
out.writeObject(lisi);
out.writeObject(wangwu);
} catch (IOException e) {
e.printStackTrace();
}
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("person.ser"));
Person one = (Person) in.readObject();
Person two = (Person) in.readObject();
Person three = (Person) in.readObject();
System.out.println("name:"+one.name + " age:"+one.age + " height:"+one.height);
System.out.println("name:"+two.name + " age:"+two.age + " height:"+two.height);
System.out.println("name:"+three.name + " age:"+three.age + " height:"+three.height);
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出结果如下:
name:zhangsan age:30 height:170
name:zhangsan age:35 height:175
name:zhangsan age:28 height:178
从添加的代码我们可以看到进行反序列化也很简单,主要用到的流是FileInputstream和ObjectInputstream正好与存储时用到的流相对应。另外从结果顺序我们可以看到反序列化后得到对象的顺序与序列化时的顺序一致。
四、总结
进行对象序列化主要目的是为了保存对象的状态(成员变量)。
进行序列化主要用到的流是FileOutputStream和ObjectOutputStream。FileOutputStream主要用于连接磁盘文件,并把字节写出到该磁盘文件;ObjectOutputStream主要用于将对象写出为可转化为字节的数据。
要将某类的对象序列化,则该类必须实现Serializable接口,该接口仅是一个标志,告诉JVM该类的对象可以被序列化。如果某类未实现Serializable接口,则该类对象不能实现序列化。
保存状态的目的就是为了在未来的某个时候再恢复保存的内容,这可以通过反序列化来实现。对象的反序列化过程与序列化正好相反,主要用到的两个流是FileInputstream和ObjectInputStream。
反序列化后得到的对象的顺序与保存时的顺序一致。
五、补充
补充一:上面我们举得例子很简单,要保存的成员变量要么是基本类型的要么是String类
型的。但有时成员变量有可能是引用类型的,这是的情况会复杂一点。那就是当要对某对象进行序列化时,该对象中的引用变量所引用的对象也会被同时序列化,并
且该对象中如果也有引用变量的话则该对象也将被序列化。总结说来就是在序列化的时候,对象中的所有引用变量所对应的对象将会被同时序列化。这意味着,引用
变量类型也都要实现Serializable接口。当然其他对象的序列化都是自动进行的。所以我们只要保证里面的引用类型是都实现Serializable接口就行了,如果没有的话,会在编译时抛出异常。如果序列化的对象中包含没有实现Serializable的成员变量的话,这时可以使用transient关键字,让序列化的时候跳过该成员变量。使用关键字transient可以让你在序列化的时候自动跳过transient所修饰的成员变量,在反序列化时这些变量会恢复到默认值。
补充二:如果某类实现了Serializable接口的话,其子类会自动编程可序列化的,这个好理解,继承嘛。
补充三:在反序列化的时候,并不会调用对象的构造器,这也好理解,如果调用了构造器的话,对象的状态不就又重新初始化了吗。
补充四:我们说到对象序列化的是为了保存对象的状态,即对象的成员变量,所以静态变量不会被序列化。
JAVA的序列化与反序列化的更多相关文章
- java 对象序列化与反序列化
Java序列化与反序列化是什么? 为什么需要序列化与反序列化? 如何实现Java序列化与反序列化? 本文围绕这些问题进行了探讨. 1.Java序列化与反序列化 Java序列化是指把Java对象转换为 ...
- Java对象序列化与反序列化一 JSON
Java对象序列化与反序列化一 JSON 1. 依赖库 jackson-all-1.6.1.jar 2. 代码 public class Student { private String nam ...
- Java对象序列化和反序列化的工具方法
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import ja ...
- Java之序列化和反序列化
序列化的对象: package test_demo.SerializableOper; import java.io.Serializable; /* * 序列化对象需要实现序列号接口 * */ pu ...
- java之序列化与反序列化
1.这里主要是介绍Protobuf提供的序列化与反序列化的高效性.相对于传统的java提供的序列化来说,Protobuf的效率提高了很多倍.但是也有不足的地方,就是proto在对象序列化的时候抛弃了很 ...
- Java基础—序列化与反序列化(转载)
转载自: Java序列化与反序列化 1.Java序列化与反序列化 Java序列化是指把Java对象转换为字节序列的过程:而Java反序列化是指把字节序列恢复为Java对象的过程. 2.为什么需要序列化 ...
- Java 中序列化与反序列化
一. 序列化和反序列化概念 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.将程序中的对象,放入文 ...
- 深入分析Java的序列化与反序列化
序列化是一种对象持久化的手段.普遍应用在网络传输.RMI等场景中.本文通过分析ArrayList的序列化来介绍Java序列化的相关内容.主要涉及到以下几个问题: 怎么实现Java的序列化 为什么实现了 ...
- Java 对象序列化和反序列化
之前的文章中我们介绍过有关字节流字符流的使用,当时我们对于将一个对象输出到流中的操作,使用DataOutputStream流将该对象中的每个属性值逐个输出到流中,读出时相反.在我们看来这种行 ...
随机推荐
- 4-Highcharts 3D图之3D普通饼图
<!DOCTYPE> <html lang='en'> <head> <title>4-Highcharts 3D图之3D普通饼图</title& ...
- ASP.NET中读取excel内容并显示
项目中经常会用到把excel的文件内容导入到数据库中的,刚刚花了点时间,做了个例子,基本上能实现导入Excel后显示的功能吧,导入的excel文件得是xls,即是2003的. 代码思路如下:要 ...
- CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
CountDownLatch,一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待. 主要方法 public CountDownLatch(int count); pu ...
- javascript实现数据结构:串--定长顺序存储表示以及kmp算法实现
串(string)(或字符串)是由零个或多个字符组成的有限序列.串中字符的数目称为串的长度.零个字符的串称为空串(null string),它的长度为零. 串中任意个连续的字符组成的子序列称为该串的子 ...
- MySQL Date 函数
MySQL Date 函数 下面的表格列出了 MySQL 中最重要的内建日期函数: 函数 描述 NOW() 返回当前的日期和时间 CURDATE() 返回当前的日期 CURTIME() 返回当前的时间 ...
- Android Activity 阻止软键盘自动弹出
在AndroidManifest.xml里面 选择那个acitivity, 把他的window soft input mode设置成stateHidden和 adjustUnspecified < ...
- intelli IDEA node开发代码提示问题
好几天没写代码了,今天新建一个项目,在引入rs这个文件系统模块时却没有关于这个模块的代码提示,着实令人恶心啊.还好最终解决了. 在没有代码提示的时候点击如下图标: 出现如下的界面,其中有个Edit u ...
- Lua的require和module小结
Lua的require和module小结 module特性是lua5.1中新增的,用于设置Lua文件自己的模块,最常用的方式是module(name,package.seeall),有时候lua文件 ...
- 4 tips for staying productive on Friday
4 tips for staying productive on Friday如何让你的周五和周一一样有效率1.Schedule Your Day with Tasks 用任务计划一天 Sometim ...
- CentOS系统配置redis
1.切换到/usr/sr cd /usr/src wget http://download.redis.io/releases/redis-3.2.0.tar.gz 2.解压,安装 tar x ...