天天看點

Java 序列化 與 反序列化

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