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接口,而没有其它任何处理的话,则就是使用默认序列化机制。使用默认机制,在序列化对象时,不仅会序列化当前对象本身,还会对该对象引用的其它对象也进行序列化,同样地,这些其它对象引用的另外对象也将被序列化,以此类推。所以,如果一个对象包含的成员变量是容器类对象,而这些容器所含有的元素也是容器类对象,那么这个序列化的过程就会较复杂,开销也较大。
原文地址:https://www.cnblogs.com/fgm119/p/3594949.html