1. 什么是序列化和反序列化?
序列化是一种将对象以一连串的字节描述的过程;反序列化是一种将这些字节重建成一个对象的过程。
2. 什么情况下需要序列化?
a)当你想把内存中的对象保存到一个文件中或者数据库的时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候;
只有被序列化的数据才允许被存储到文件、数据库之中或者通过网络协议进行传输,没有被序列化的数据是不能存储到硬盘上,不能通过网络协议进行网络传输。
3. 如何实现序列化?
将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表示这个类可以序列化。只要这个类实现了Serializable接口,这个类的所有属性和方法都会自动序列化。然而在实际开发过程中,我们常常会遇到这样的问题,这个类的有些属性需要序列化,而其他属性不需要被序列化,打个比方,如果一个用户有一些敏感信息(如密码、银行卡号等),为了安全起见,不希望在网络操作(主要涉及到序列化操作,本地序列化缓存也适用)中被传输,这些信息对应的变量就可以加上transient关键字。换句话说,这个字段的生命周期仅存于调用者的内存中而不会写到磁盘里持久化。
4. 序列化和反序列化例子
如果我们想要序列化一个对象的步骤:
①创建某些OutputStream(如FileOutputStream、ByteArrayOutputStream等)
②将这些OutputStream封装在一个ObjectOutputStream中
③调用writeObject()方法就可以将对象序列化,并将其发送给OutputStream(记住:对象的序列化是基于字节的,不能使用Reader和Writer等基于字符的层次结构)。
反序列的过程(即将一个序列还原成为一个对象),需要将一个InputStream(如FileInputstream、ByteArrayInputStream等)封装在ObjectInputStream内,然后调用readObject()即可。
实例1:
package serializableDemo;
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.io.Serializable;
public class Main_seria implements Serializable {
private static final long serialVersionUID = 1L;
private String name = "SheepMu";
private int age = 24;
public static void main(String[] args) {// 以下代码实现序列化
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("my.out"));// 输出流保存的文件名为
// my.out
// ;ObjectOutputStream能把Object输出成Byte流
Main_seria myTest = new Main_seria();
oos.writeObject(myTest);
oos.flush(); // 缓冲流
oos.close(); // 关闭流
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
fan();// 调用下面的 反序列化 代码
}
public static void fan()// 反序列的过程
{
ObjectInputStream oin = null;// 局部变量必须要初始化
try {
oin = new ObjectInputStream(new FileInputStream("my.out"));
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
Main_seria mts = null;
try {
mts = (Main_seria) oin.readObject();// 由Object对象向下转型为Main_seria对象
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("name=" + mts.name);
System.out.println("age=" + mts.age);
}
}
实例2:
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.io.Serializable;
/**
* @description 使用transient关键字不序列化某个变量
* 注意读取的时候,读取数据的顺序一定要和存放数据的顺序保持一致
*
* @author Alexia
* @date 2013-10-15
*/
public class TransientTest {
public static void main(String[] args) {
User user = new User();
user.setUsername("Alexia");
user.setPasswd("123456");
System.out.println("read before Serializable: ");
System.out.println("username: " + user.getUsername());
System.err.println("password: " + user.getPasswd());
try {
ObjectOutputStream os = new ObjectOutputStream(
new FileOutputStream("C:/user.txt"));
os.writeObject(user); // 将User对象写进文件
os.flush();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
ObjectInputStream is = new ObjectInputStream(new FileInputStream(
"C:/user.txt"));
user = (User) is.readObject(); // 从流中读取User的数据
is.close();
System.out.println("\nread after Serializable: ");
System.out.println("username: " + user.getUsername());
System.err.println("password: " + user.getPasswd());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class User implements Serializable {
private static final long serialVersionUID = 8294180014912103005L;
private String username;
private transient String passwd;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}
输出为:
read before Serializable:
username: Alexia
password: 123456
read after Serializable:
username: Alexia
password: null