对象序列化的概念
对象序列化使得一个程序可以把一个完整的对象写到一个字节流里面;其逆过程则是从一个字节流里面读出一个事先存储在里面的完整的对象,称为对象的反序列化。
将一个对象保存到永久存储设备上称为持续性。对象的序列化即可实现持续性。
一个对象要想能够实现序列化,必须实现 Serializable 接口或 Externalizable 接口。
对象序列化的作用
一、对象序列化可以实现分布式对象。主要应用例如:RMI(远程方法调用)要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。
二、对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的"深复制",即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。
对象序列化的相关说明
一、如果某个类能够被序列化,其子类也可以被序列化。
二、声明为 static和transient 类型的成员数据不能被序列化。因为 static 代表类的状态, transient 代表对象的临时数据。
三、当一个对象被序列化时,只保存对象的非静态成员变量,不能保存任何的成员方法和静态的成员变量。
四、如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
五、如果一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操作将会失败,并且会抛出一个NotSerializableException。我们可以将这个引用标记为transient,那么对象仍然可以序列化。
对象序列化的Java实现代码
我们以实现Serializable接口来为例来进行相关操作。
先定义一个类 Person:
class Person implements Serializable { private static final long serialVersionUID = 1L; int age; String name; static int i = 100; transient int k = 2; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void m1(){ System.out.println(age + "-" + name + "-" + i + "-" + k); } }
对象序列化的实现:
Java方法代码
//序列化(串行化) public static void ser(Person p, String fileName){ ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new FileOutputStream(new File(fileName))); oos.writeObject(p); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
实现范例
public static void main(String[] args) { Person p = new Person(); p.age = 100; p.name = "007"; String fileName = "obj.txt"; ser(p,fileName); }
如此,可以在项目目录下生成 obj.txt。即完成了对象的序列化。
对象反序列化的实现:
Java 方法代码:
//反序列化(并行化) public static void unSer(String fileName){ try { ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(fileName))); Person p = (Person)ois.readObject(); System.out.println(p.getAge() + p.getName()); p.m1(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }
实现范例
为了验证对象反序列化的实现,我们将与对象序列化有关的代码注释掉。
public static void main(String[] args) { // Person p = new Person(); // p.age = 100; // p.name = "007"; String fileName = "obj.txt"; // ser(p,fileName); unSer(fileName); }
输出如下:
---------- 运行 ----------
100007
100-007-100-0
输出完成 (耗时 0 秒) - 正常终止
则证明我们对象反序列化成功。