zoukankan      html  css  js  c++  java
  • 每天进步一点点-Java IO操作-Java Serializable(对象序列化)的理解和总结

    硬盘文件里写数据


    序列化:序列化是将对象转换为容易传输的格式的过程。例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。在另一端,反序列化将从该流重新构造对象。 

    对象永久化的一种机制。 

    确切的说应该是对象的序列化,一般程序在运行时,产生对象,这些对象随着程序的停止运行而消失,但如果我们想把某些对象(因为是对象,所以有各自不同的特性)保存下来,在程序终止运行后,这些对象仍然存在,可以在程序再次运行时读取这些对象的值,或者在其他程序中利用这些保存下来的对象。这种情况下就要用到对象的序列化。 只有序列化的对象才可以存储在存储设备上。

    为了对象的序列化而需要继承的接口也只是一个象征性的接口而已,也就是说继承这个接口说明这个对象可以被序列化了,没有其他的目的。之所以需要对象序列化,是因为有时候对象需要在网络上传输,传输的时候需要这种序列化处理,从服务器硬盘上把序列化的对象取出,然后通过网络传到客户端,再由客户端把序列化的对象读入内存,执行相应的处理。 


    1、序列化是干什么的?
           简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。

    2、什么情况下需要序列化   
        a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
        b)当你想用套接字在网络上传送对象的时候;
        c)当你想通过RMI传输对象的时候;

    3、当对一个对象实现序列化时,究竟发生了什么?
        在没有序列化前,每个保存在堆(Heap)中的对象都有相应的状态(state),即实例变量(instance ariable)比如:
       

    java 代码
    1. Foo  myFoo = new Foo();  
    2. myFoo .setWidth(37);  
    3. myFoo.setHeight(70);  

           游戏的存档
           当 通过下面的代码序列化之后,MyFoo对象中的width和Height实例变量的值(37,70)都被保存到foo.ser文件中,这样以后又可以把它 从文件中读出来,重新在堆中创建原来的对象。当然保存时候不仅仅是保存对象的实例变量的值,JVM还要保存一些小量信息,比如类的类型等以便恢复原来的对 象。

    java 代码
    1. FileOutputStream fs = new FileOutputStream("foo.ser");  
    2. ObjectOutputStream os = new ObjectOutputStream(fs);  
    3. os.writeObject(myFoo);  


    4、实现序列化(保存到一个文件)的步骤
           
    a)Make a FileOutputStream            

    java 代码
    1. FileOutputStream fs = new FileOutputStream("foo.ser");    

           b)Make a ObjectOutputStream            

    java 代码
    1. ObjectOutputStream os =  new ObjectOutputStream(fs);   

           c)write the object

    java 代码
    1. os.writeObject(myObject1);  
    2. os.writeObject(myObject2);  
    3. os.writeObject(myObject3);  

        d) close the ObjectOutputStream

    java 代码
    1. os.close();  



    5、举例说明

    java 代码
    1. import java.io.*;
    2.   
    3. public class  Box implements Serializable  
    4. {  
    5.     private int width;  
    6.     private int height;  
    7.   
    8.     public void setWidth(int width){  
    9.         this.width  = width;  
    10.     }  
    11.     public void setHeight(int height){  
    12.         this.height = height;  
    13.     }  
    14.   
    15.     public static void main(String[] args){  
    16.         Box myBox = new Box();  
    17.         myBox.setWidth(50);  
    18.         myBox.setHeight(30);  
    19.   
    20.         try{  
    21.             FileOutputStream fs = new FileOutputStream("foo.ser");  
    22.             ObjectOutputStream os =  new ObjectOutputStream(fs);  
    23.             os.writeObject(myBox);  
    24.             os.close();  
    25.         }catch(Exception ex){  
    26.             ex.printStackTrace();  
    27.         }  
    28.     }  
    29.       
    30. }  


    6、相关注意事项
        a)序列化时,只对对象的状态进行保存,而不管对象的方法;
        b)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
        c)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
        d)并非所有的对象都可以序列化,,至于为什么不可以,有很多原因了,比如:
            1.安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输  等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。
           2. 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分  配,而且,也是没有必要这样实现。

  • 相关阅读:
    linux下vim的安装及其设置细节
    vm虚拟机下ubuntu连接上ssr
    文件写入-结构体排序
    利用链表进行报数游戏
    链表——尾插法
    C#设计模式总结
    C#设计模式(20)——策略者模式(Stragety Pattern)
    Autofac在项目中应用的体会,一个接口多个实现的情况
    C#设计模式(1)——单例模式
    jquery.js与sea.js综合使用
  • 原文地址:https://www.cnblogs.com/cs-lcy/p/7352155.html
Copyright © 2011-2022 走看看