Java對象序列化

   對於一個存在Java虛擬機中的對象來說,其內部的狀態只是保存在內存中。JVM退出之後,內存資源也就被釋放,Java對象的內部狀態也就丟失了。而在很多情況下,對象內部狀態是需要被持久化的,將運行中的對象狀態保存下來(最直接的方式就是保存到文件系統中),在需要的時候可以還原,即使是在Java虛擬機退出的情況下。

   對象序列化機制是Java內建的一種對象持久化方式,可以很容易實現在JVM中的活動對象與字節數組(流)之間進行轉換,使用得Java對象可以被存儲,可以被網絡傳輸,在網絡的一端將對象序列化成字節流,經過網絡傳輸到網絡的另一端,可以從字節流重新還原爲Java虛擬機中的運行狀態中的對象。

1.相關的接口

      Java類中對象的序列化工作是通過ObjectOutputStream和ObjectInputStream來完成的。         

   

Java代碼 複製代碼 收藏代碼
  1. ObjectOutputStream(OutputStream out);   
  2.     void writeObject(Object obj);//將指定的對象的非transient,非static屬性,寫入ObjectOutputStream   
  3.       
  4.     ObjectInputStream(InputStream in);   
  5.     Object readObject();//從指定的流中讀取還原對象信息  



    只能使用readObject()|writeObject()方法對對象進行讀寫操作。除對象之外,Java中的基本類型和數組也可以被序列化,對於基本類型,可以使用readInt(),writeInt(),
readDouble(),writeDouble()等類似的接口進行讀寫。


2.Serializable接口 

    對於任何需要被序列化的對象,都必須要實現接口Serializable,它只是一個標識接口,本身沒有任何成員,只是用來標識說明當前的實現類的對象可以被序列化.


3.transient關鍵字
 
    如果在類中的一些屬性,希望在對象序列化過程中不被序列化,使用關鍵字transient標註修飾就可以.當對象被序列化時,標註爲transient的成員屬性將會自動跳過。

 
4.Java序列化中需要注意:

      (1).當一個對象被序列化時,只保存對象的非靜態成員變量,不能保存任何的成員方法,靜態的成員變量和transient標註的成員變量。

     (2).如果一個對象的成員變量是一個對象,那麼這個對象的數據成員也會被保存還原,而且會是遞歸的方式。

     (3).如果一個可序列化的對象包含對某個不可序列化的對象的引用,那麼整個序列化操作將會失敗,並且會拋出一個NotSerializableException。可以將這個引用標記transient,那麼對象仍然可以序列化。


5.一個綜合實例:

 

Java代碼 複製代碼 收藏代碼
  1. class Student implements Serializable{   
  2.        
  3.     private String name;   
  4.     private transient int age;   
  5.     private Course course;   
  6.        
  7.     public void setCourse(Course course){   
  8.         this.course = course;   
  9.     }   
  10.        
  11.     public Course getCourse(){   
  12.         return course;   
  13.     }   
  14.        
  15.     public Student(String name, int age){   
  16.         this.name = name;   
  17.         this.age = age;   
  18.     }   
  19.   
  20.     public String  toString(){   
  21.         return "Student Object name:"+this.name+" age:"+this.age;   
  22.     }   
  23. }   
  24.   
  25. class Course implements Serializable{   
  26.        
  27.     private static String courseName;   
  28.     private int credit;   
  29.        
  30.     public Course(String courseName, int credit){   
  31.         this.courseName  = courseName;   
  32.         this.credit = credit;   
  33.     }   
  34.        
  35.     public String toString(){   
  36.            
  37.         return "Course Object courseName:"+courseName   
  38.                +" credit:"+credit;   
  39.     }   
  40. }  



將對象寫入文件,序列化
 

Java代碼 複製代碼 收藏代碼
  1. public class TestWriteObject{   
  2.   
  3.     public static void main(String[] args) {   
  4.   
  5.         String filePath = "C://obj.txt";   
  6.         ObjectOutputStream objOutput = null;   
  7.         Course c1 = new Course("C language"3);   
  8.         Course c2 = new Course("OS"4);   
  9.            
  10.         Student s1 = new Student("king"25);   
  11.         s1.setCourse(c1);   
  12.            
  13.         Student s2 = new Student("jason"23);   
  14.         s2.setCourse(c2);   
  15.   
  16.         try {   
  17.             objOutput = new ObjectOutputStream(new FileOutputStream(filePath));   
  18.             objOutput.writeObject(s1);   
  19.             objOutput.writeObject(s2);   
  20.             objOutput.writeInt(123);   
  21.         } catch (FileNotFoundException e) {   
  22.             e.printStackTrace();   
  23.         } catch (IOException e) {   
  24.             e.printStackTrace();   
  25.         }finally{   
  26.             try {   
  27.                 objOutput.close();   
  28.             } catch (IOException e) {   
  29.                 e.printStackTrace();   
  30.             }   
  31.         }   
  32.            
  33.         System.out.println("Info:對象被寫入"+filePath);   
  34.     }  



從文件中讀取對象,反序列化
 

Java代碼 複製代碼 收藏代碼
  1. public class TestReadObject  {   
  2.        
  3.     public static void main(String[] args) {   
  4.            
  5.         String filePath = "C://obj.txt";   
  6.         ObjectInputStream objInput = null;   
  7.         Student s1 = null,s2 = null;   
  8.         int intVal = 0;   
  9.        
  10.         try {   
  11.             objInput = new ObjectInputStream(new FileInputStream(filePath));   
  12.             s1 = (Student)objInput.readObject();   
  13.             s2 = (Student)objInput.readObject();   
  14.             intVal = objInput.readInt();   
  15.                
  16.         } catch (FileNotFoundException e) {   
  17.             e.printStackTrace();   
  18.         } catch (IOException e) {   
  19.             e.printStackTrace();   
  20.         }catch(ClassNotFoundException cnfe){   
  21.             cnfe.printStackTrace();   
  22.         }finally{   
  23.                
  24.             try {   
  25.                 objInput.close();   
  26.             } catch (IOException e) {   
  27.                 e.printStackTrace();   
  28.             }   
  29.         }   
  30.            
  31.         System.out.println("Info:文件"+filePath+"中讀取對象");   
  32.         System.out.println(s1);   
  33.         System.out.println(s1.getCourse());   
  34.         System.out.println(s2);   
  35.         System.out.println(s2.getCourse());   
  36.         System.out.println(intVal);   
  37.     }   
  38. }  



輸出:

[TestWriteObject]
Info:對象被寫入C://obj.txt

[TestReadObjec]
Info:文件C://obj.txt中讀取對象
Info:文件C://obj.txt中讀取對象
Student Object name:king age:0
Course Object courseName:null credit:3
Student Object name:jason age:0
Course Object courseName:null credit:4
123


可知Person中的age屬性被標註爲transient後,在序列化對象時,age屬性就沒有被序列化了; Course中的name屬性被static後,Course的name靜態屬性就沒有被序列化;雖然是序列化Person對象,但是Person所引用的Course對象也被初始化了。 
  


http://yuyiming.iteye.com/blog/1277089

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章