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

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对象也被初始化了。 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐