1、什么是序列化与反序列化? - Y2 ] n' O& z, `( v8 n B' R 序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。一般将一个对象存储至一个储存媒介,例如档案或是记亿体缓冲等。在网络传输过程中,可以是字节或是XML等格式。而字节的或XML编码格式可以还原完全相等的对象。这个相反的过程又称为反序列化。 4 J( P; v. E7 _( b+ r5 j. o( H2、Java如何实现序列化和反序列化?* k: T4 r9 s. e% d6 h0 w
在Java中,我们可以通过多种方式来创建对象,并且只要对象没有被回收我们都可以复用该对象。但是,我们创建出来的这些Java对象都是存在于JVM的堆内存中的。只有JVM处于运行状态的时候,这些对象才可能存在。一旦JVM停止运行,这些对象的状态也就随之而丢失了。 8 \& z T+ s% A3 s: Z, g h& M 但是在真实的应用场景中,我们需要将这些对象持久化下来,并且能够在需要的时候把对象重新读取出来。Java的对象序列化可以帮助我们实现该功能。 / f$ Q% i- ?" _9 U 对象序列化机制(object serialization)是Java语言内建的一种对象持久化方式,通过对象序列化,可以把对象的状态保存为字节数组,并且可以在有需要的时候将这个字节数组通过反序列化的方式再转换成对象。对象序列化可以很容易的在JVM中的活动对象和字节数组(流)之间进行转换。) t m Z6 P$ z$ C/ O
在Java中,对象的序列化与反序列化被广泛应用到RMI(远程方法调用)及网络传输中。 & D3 m3 _ @" U. M2 y5 } 在Java中,只要一个类实现了java.io.Serializable接口,那么它就可以被序列化。这里先来一段代码:7 h8 s' ?$ L9 F
创建一个User类,用于序列化及反序列化 4 [5 K! m, t# U* w. O' H z
public class SerializableDemo {
public static void main(String[] args) {
//Initializes The Object
User user = new User();
user.setName("hollis");
user.setGender("male");
user.setAge(23);
user.setBirthday(new Date());
System.out.println(user);
//Write Obj to File
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("tempFile"));
oos.writeObject(user);
} catch (IOException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(oos);
}
//Read Obj from File
File file = new File("tempFile");
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream(file));
User newUser = (User) ois.readObject();
System.out.println(newUser);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
IOUtils.closeQuietly(ois);
try {
FileUtils.forceDelete(file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//output
//User{name='hollis', age=23, gender=male, birthday=Tue Feb 02 17:37:38 CST 2016}
//User{name='hollis', age=23, gender=null, birthday=Tue Feb 02 17:37:38 CST 2016}
1、在Java中,只要一个类实现了java.io.Serializable接口,那么它就可以被序列化。0 f6 z, v- C7 l( q% z
2、通过ObjectOutputStream和ObjectInputStream对对象进行序列化及反序列化 . R/ E+ c8 }9 x& L/ Z1 R. X( O3、虚拟机是否允许反序列化,不仅取决于类路径和功能代码是否一致,一个非常重要的一点是两个类的序列化 ID 是否一致(就是 private static final long serialVersionUID)% ?. Y. V ^3 C$ u
4、序列化并不保存静态变量。% m2 n/ c- ]' n/ Y, k7 Y
5、要想将父类对象也序列化,就需要让父类也实现Serializable 接口。9 Y0 }- N: o1 a g$ M( b
6、Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null。 ( m) l$ g+ |' S l- f# x, N; [, ?7、服务器端给客户端发送序列化对象数据,对象中有一些数据是敏感的,比如密码字符串等,希望对该密码字段在序列化时,进行加密,而客户端如果拥有解密的密钥,只有在客户端进行反序列化时,才可以对密码进行读取,这样可以一定程度保证序列化对象的数据安全。( W2 |8 M. W2 ^) D/ o 3、如何自定义序列化和反序列化呢? 9 I3 P9 @$ l0 X4 g1 Y
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
transient Object[] elementData; // non-private to simplify nested class access
private int size;
}