1- 什麼是序列化:序列化就是将對象 進行流化(轉化為流的形式),并攜帶唯一辨別 UID-序列化版本号,進行傳輸、通信。此外,你還可以持久化到檔案(FileOutputStream流),資料庫中(ORM思想)。
2- 為什麼要序列化:類似Socket通信中,傳輸的資料以位元組流的形式在伺服器端和用戶端之間傳輸通信,對象要是想在網絡中進行傳輸通信話,或是進行讀寫操作,也要轉化為流的形式,即需要序列化。
3- 怎麼實作序列化:java實作序列化,即一個對象類 要實作Serializable接口。并建議賦予其序列化版本号UID值(原因在後面4講到)。一方使用ObjectOutput接口的實作類ObjectOutputStream 提供的寫方法:ObjectWrite将對象序列化到流,或持久化到本地檔案,另一方使用ObjectInput接口的實作類ObjectInputStream提供的讀方法:ObjectRead 從流中或是檔案中反序列化為原對象。
4- 序列化要注意的問題:
|-要序列化的對象要實作Serializable接口,才能被編譯器序列化。
|-要序列化的實體類要有唯一辨別serialVersionUID,它是作為檢驗序列化的對象是否是同一個對象版本的唯一辨別。如果對已序列化的對象再次進行修改,那麼,這個辨別值就會被編譯器再次編譯所改變。反序列化的話就會出現問題。是以,建議在實作序列化的時候,給出其serialVersionUID 的值。
對象序列化 執行個體-1:[Socket通信中對象序列化進行通信]
要序列化的對象類:Student
<span style="font-size:14px;">packagecom.entity;
importjava.io.Serializable;
publicclass Student implements Serializable{
private static final longserialVersionUID = 1L;
private String name;
private String sex;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result +age;
result = prime * result +((name == null) ? 0 : name.hashCode());
result = prime * result +((sex == null) ? 0 : sex.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() !=obj.getClass())
return false;
Student other = (Student)obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name !=null)
returnfalse;
} else if(!name.equals(other.name))
return false;
if (sex == null) {
if (other.sex !=null)
returnfalse;
} else if(!sex.equals(other.sex))
return false;
return true;
}
@Override
public String toString() {
return "Student[age=" + age + ", name=" + name + ", sex=" + sex +"]";
}
}</span>
用戶端類:SocketClient
<span style="font-size:14px;">packagecom.client;
importjava.io.IOException;
importjava.io.ObjectOutputStream;
importjava.net.Socket;
importjava.net.UnknownHostException;
importcom.entity.Student;
publicclass SocketClient {
private String host;
private int port;
public SocketClient(String host, intport) {
this.host = host;
this.port = port;
}
public void client() throwsUnknownHostException, IOException {
Student s = newStudent();
s.setAge(20);
s.setName("luxury");
s.setSex("Man");
Socket socket = newSocket(host, port);
System.out.println("連接配接建立-");
ObjectOutputStreamoos = new ObjectOutputStream(socket
.getOutputStream());
oos.writeObject(s);//對象序列化
System.out.println("對象 發送完畢!");
oos.flush();
socket.close();
}
public static void main(String[] args)throws UnknownHostException,
IOException {
newSocketClient("localhost", 8009).client();
}
}</span>
伺服器端類:SocketServer
<span style="font-size:14px;">packagecom.server;
importjava.io.IOException;
importjava.io.ObjectInputStream;
importjava.net.ServerSocket;
importjava.net.Socket;
importcom.entity.Student;
publicclass SocketServer {
private int port;
public SocketServer(int port){
this.port = port;
}
public void service() throwsIOException, ClassNotFoundException, InterruptedException{
ServerSocket server = newServerSocket(port);
Socket socket =server.accept();
System.out.println("有連接配接進來!");
// Thread.sleep(1000);
ObjectInputStream ois = newObjectInputStream(socket.getInputStream());
Student student =(Student)ois.readObject();//對象反序列化為原對象
System.out.println(student.getName()+"的資訊如下 :"+student.toString());
ois.close();
socket.close();
}
public static void main(String[] args)throws IOException, ClassNotFoundException, InterruptedException {
newSocketServer(8009).service();
}
}</span>
Console結果:
用戶端:
連接配接建立-
對象 發送完畢!
伺服器端:
有連接配接進來!
luxury 的資訊如下 : Student [age=20,name=luxury, sex=Man]
對象序列化 執行個體-2:對象序列化到檔案
要序列化的對象類:Student
<span style="font-size:14px;">import java.io.Serializable;
/**
* 建立 Student 對象,并 實作 序列化 Serializable
* @author lu
*
*/
publicclass Student implements Serializable{
private static final longserialVersionUID = 2L;
private String name;
private int age;
private String grade;
private double salary;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGrade() {
return grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result +age;
result = prime * result +((grade == null) ? 0 : grade.hashCode());
result = prime * result +((name == null) ? 0 : name.hashCode());
long temp;
temp =Double.doubleToLongBits(salary);
result = prime * result +(int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() !=obj.getClass())
return false;
Student other = (Student)obj;
if (age != other.age)
return false;
if (grade == null) {
if (other.grade !=null)
returnfalse;
} else if(!grade.equals(other.grade))
return false;
if (name == null) {
if (other.name !=null)
returnfalse;
} else if(!name.equals(other.name))
return false;
if(Double.doubleToLongBits(salary) != Double
.doubleToLongBits(other.salary))
return false;
return true;
}
@Override
public String toString(){
return "name="+name+";age="+age+"; salary="+salary+";grade="+grade;
}
}</span>
序列化到檔案和從檔案反序列化類:
<span style="font-size:14px;">importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
importjava.io.ObjectInputStream;
importjava.io.ObjectOutputStream;
/**
* 序列化 測試
* @author lu
*
*/
publicclass SerializableTest {
public static void main(String[] args){
objectIntoSerializable();
// serializableIntoObject();
}
/**
* 從 對象 實作序列化 到 檔案
*/
public static voidobjectIntoSerializable() {
Student student = newStudent();
student.setAge(8);
student.setGrade("初三");
student.setName("小花");
student.setSalary(1000);
//ObjectOutputStream 類
ObjectOutputStream oos =null;
try {
oos = newObjectOutputStream( new FileOutputStream("R:\\Object.txt", true));
//将 對象 寫入 位元組流
oos.writeObject(student);
System.out.println("======寫入OK=====");
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
oos.close();
} catch (IOExceptione) {
e.printStackTrace();
}
}
}
/**
* 從 檔案 反序列化 到 對象
*/
public static voidserializableIntoObject() {
//ObjectInputStream 根據 位元組流 重構對象
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(
newFileInputStream("R:\\Object.txt"));
Student s =(Student) ois.readObject();
System.out.println(s.toString());
} catch(FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch(ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
ois.close();
} catch (IOExceptione) {
e.printStackTrace();
}
}
}
}</span>
Console結果:
序列化結果-
======寫入OK=====
反序列化結果-
name=小花; age=8;salary=1000.0;grade=初三
Object.txt檔案内容:
sr Student