在Java中,序列化其實有兩個用處,保存和傳送數據。
保存數據:將對象的狀態持久保存在存儲媒體(數據庫或文件系統)上,以後可以重新創建精確的副本。
Java允許我們在內存中創建可複用的Java對象,但一般情況下,只有當JVM處於運行時,這些對象纔可能存在,也就是說,如果JVM停止了,原本佔用的內存被釋放,對象自然也不復存在。如果要求在JVM停止運行之後能夠保存指定的對象,並在將來重新讀取被保存的對象,Java對象序列化就能夠實現。使用Java對象序列化,在保存對象時,會把其狀態保存爲一組字節,以後如果要用到這個對象,就可以通過反序列化,將這些字節組裝成對象。注意,對象序列化保存的是對象的"狀態",即它的成員變量,而靜態變量屬於類的狀態,由此可知,對象序列化不會關注類中的靜態變量。
傳送數據:將對象從一個應用程序域發送到另一個應用程序域中(遠程調用RMI)。
當兩個進程在進行遠程通信時,彼此可以發送各種類型的數據。無論是何種類型的數據,都會以二進制序列的形式在網絡上傳送。發送方需要把這個對象轉換爲字節序列,才能在網絡上傳送;接收方則需要把字節序列再恢復爲對象,而不是通過構造方法新建一個新的對象再賦予原來的值。將對象轉化爲流的過程其實就是序列化(Serialization),而將流重新轉化成對象的過程則是反序列化(Deserialization)。
下面是序列化對象信息:
public class Person implements Serializable
{
private static final long serialVersionUID = 1L;
private int age;
private String name;
public Person(String name, int age)
{
this.age = age;
this.name = name;
}
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;
}
@Override
public String toString()
{
return "Person [ name = " + name + ", age = " + age + " ]";
}
}
上面代碼有: private static final long serialVersionUID = 1L;
這個序列化ID的作用是用來決定是否可以反序列化。如果有兩個類,都實現了Serializable,且功能代碼完全一致,一個負責序列化,另一個負責反序列化,如果兩者的序列化ID不同,那麼不能相互序列化和反序列化。
public class Test
{
public static void main(String[] args)
{
write();
read();
}
private static void write()
{
Person student = new Person("shawn", 18);
try
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("seria.txt"));
out.writeObject(student); //
System.out.println("Object has been written.");
out.close();
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
}
}
private static void read()
{
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("seria.txt"));
Person studentRead = (Person) in.readObject();
System.out.println("Object is:");
System.out.println(studentRead);
in.close();
} catch (FileNotFoundException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.printStackTrace();
} catch (ClassNotFoundException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}