• j对ava序列化的学习理解


    1,为何要实现序列化

     Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。实际上序列化就是将java对象转化成字节序列,这些字节可以被保存到磁盘上,也可以借助网络进行传输,序列化后的对象以二进制形式保存,这样就实现了平台的无关性,Windows平台上的序列化对象,传输到UNIX平台,可以通过反序列化得到对象。
        必须注意地是,对象序列化保存的是对象的"状态",即它的公有成员,私有成员以及类名转化成字节流,再把字节流写入写入数据流中,存储到介质中。由此可知,对象序列化不会关注类中的静态变量。
    2,序列化的过程

      序列化机制允许将实现序列化的java对象转化成字节序列,这个过程需要借助I/O流来实现,因此只有实现了java.io.Serializable接口的类才能被序列化,JDK中,String类,Date类包装类以及枚举类型java.lang.Enum,都实现了Serializable接口,可以直接运用I/O流操作。

      对于一般对象,序列化步骤,(1)创建一个对象输出流(ObjectOutputStream),她可以包装成其他类型的输出流,如文件流FileOutputSream如下代码

    ObjectOuputStream oos=new ObjectOutputStream(new FileoutputStream("C:\myDocstu.txt"));这就创建了一个对象输出流,她包装了一个文件输出流,即

    C:\myDocstu.txt;(2)通过对象输出流的writeObject()方法写对象,将对象写入要保存的地址当中,即C:\myDocstu.txt。条件是Student类实现Serializable接口,并创建对象Student stu=new Student();oos.writeObject(stu)可以将stu对象信息保存到磁盘上。

    3, transient关键字,保密信息,未被序列化

     当某个字段被声明为transient后,默认序列化机制就会忽略该字段。此处将Person类中的age字段声明为transient,如下所示,

    public class Student implements Serializable {
        private String name = null;
        transient  private Integer age = null;
        
    private Gender gender = null;
    ...setter和getter方法
     
      public String toString() {
            
    return "[" + name + "" + age + "" + gender + "]";
        }

    }

    再执行SimpleSerial应用程序,会有如下输出:

    控制台:
    [John, 
    null, MALE]
    4,反序列化步骤与序列化类似
     
    (1)创建一个对象输出流,ObjectInputStream ois=new ObjectInputStream(new FileInputStream("c:\stu.txt"));
      (2)通过对象输出流的readObject()方法读取对象,如果返回的为object类型对象,可以将该对象强转成真实类型。
    下面是个序列化和反序列化的例子:
    SimpleSerial,是一个简单的序列化程序,它先将一个Person对象保存到文件person.out中,然后再从该文件中读出被存储的Person对象,并打印该对象。
    public class SimpleSerial {
        
    public static void main(String[] args) throws Exception {
            File file 
    = new File("c:\student.txt");

            ObjectOutputStream oout 
    = new ObjectOutputStream(new FileOutputStream(file));
            Person person 
    = new Person("John"101, MALE);
            oout.writeObject(person);
            oout.close();

            ObjectInputStream oin 
    = new ObjectInputStream(new FileInputStream(file));
            Object newPerson 
    = oin.readObject(); // 没有强制转换到Person类型由于有Student类toString方法的存在,打印该对象,就会直接调用toString方法
            oin.close();
            System.out.println(newPerson);
        }
    }
    5,默认序列化机制
        如果仅仅只是让某个类实现Serializable接口,而没有其它任何处理的话,则就是使用默认序列化机制。使用默认机制,在序列化对象时,不仅会序列化当前对象本身,还会对该对象引用的其它对象也进行序列化,同样地,这些其它对象引用的另外对象也将被序列化,以此类推。所以,如果一个对象包含的成员变量是容器类对象,而这些容器所含有的元素也是容器类对象,那么这个序列化的过程就会较复杂,开销也较大。
  • 相关阅读:
    ubuntu系统安装Loadrunner压力机和负载端(linux agent)
    LoadRunner生成二进制参数的方法
    [02]树莓派无线USB网卡,Mercury WIFI配置
    6.4节“末端端接器的交流偏置”
    MIPS32的DIV和DIVU实现(除法指令)
    5.3节“开槽地平面的串扰”
    给自己挖坑
    电容降额
    MIPS32的ADDI和ADDIU的实现要点(加法指令)
    使用加法器实现减法
  • 原文地址:https://www.cnblogs.com/fgm119/p/3594949.html
Copyright © 2020-2023  润新知