串行化(序列化)它是指将对象存储到介质(如文件、内在缓冲区等)中或是以二进制方式通过网络传输。之后可以通过反串行化从这些连续的字节(byte)数据重新构建一个与原始对象状态相同的对象,因此在特定情况下也可以说是得到一个副本,但并不是所有情况都这样。序列化时,transient变量和类变量(静态变量)不会被序列化。
Java提供了自动串行化的机制,被串行化的类必须是实现java.io.Serializable接口。这是一个标志接口。
下面是一个简单的自动串行化的例子:
import java.io.Serializable; public class Employee implements Serializable{ private String name; public Employee(String name) { this.name=name; } public String getName() { return name; } }
public class TestSerEmployee { public static void main(String[] args) { String filename="Employee.ser"; Employee emp=new Employee("kopack"); try { FileOutputStream f=new FileOutputStream(filename); ObjectOutputStream oos=new ObjectOutputStream(f); oos.writeObject(emp); oos.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
这个程序运行会生成一个
Employee.ser 文件,文件里面包含了对象串行化的信息。
有了这个文件,我们就可以解串行化:
public class RestoreEmployee { public static void main(String[] args) { String filename="Employee.ser"; Employee emp=null; try { FileInputStream f=new FileInputStream(filename); ObjectInputStream ois=new ObjectInputStream(f); emp=(Employee)ois.readObject(); System.out.println("the name is "+emp.getName()); ois.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
输出:the name is kopack
得到的emp对象跟我们保存进去的对象的信息是一样的。说明我们已经将对象的状态保存下来了。
可以看到,串行化和解串行化正好相反:
FileOutputStream f=new FileOutputStream(filename);
ObjectOutputStream oos=new ObjectOutputStream(f);
oos.writeObject(emp);
FileInputStream f=new FileInputStream(filename);
ObjectInputStream ois=new ObjectInputStream(f);
emp=(Employee)ois.readObject();
Java中ObjectInputStream 与 ObjectOutputStream这两个包装类可用于输入流中读取对象类数据和将对象类型的数据写入到底层输入流 。ObjectInputStream 与 ObjectOutputStream 类所读写的对象必须实现了 Serializable 接口。需要注意的是:对象中的 transient 和 static 类型的成员变量不会被读取和写入 。
ObjectInputStream 方法 readObject() Read an object from the ObjectInputStream.
transient
是java语言的关键字,变量修饰符,如果用transient声明一个实例变量,当对象存储时,它的值不需要维持。
Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serialization,可以在这个域前加上关键字transient。当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,然而非transient型的变量是被包括进去的。