【黑马程序员】java中----------对象的序列化与反序列化

来源:互联网 发布:java中api接口教程 编辑:程序博客网 时间:2024/06/05 05:47

---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------


1.对象的序列化:将对象读取到字节流中并且写入硬盘进行持久化保存,并且以后还可以读取使用这个对象。

这种机制叫做对象的序列化。也就是,将对象通过读取并且以字节流的方式写入知道的可以存储的区域,进行长期的保存


2.序列化的目的:就是指定的对象进行单独的存储起来,在需要用到的时候,我们可以通过反序列化的方式将其还原出来

这种方式就是为了对象的持久化。

3.一个对象进行序列化存储,前提必须实现Serializable接口,或者实现Externalizable接口;因为

Externallizable接口继承Serializable接口

通过查看API 我们知道;Serializable接口没有任何属性和方法,称为一种标记,只要有这个标记,说明

这个对象可以被序列化。

4.反序列化:反序列化就是将序列化存储对象,从新加载进内存,并且能够使用

称为反序列化。

5.当一个实现了Serializable类的对象中包含里了或者应用了其他对象,也就是说这个对象中嵌套了其他对象,同样

这些对象同时可以被序列化,同时在反序列化中,所有对象一样可以被还原。

6.当一个对象呗序列化的时候,只会保存非静态的成员变量,不能保存任何静态的成员变量,也不能保存

任何实例方法,这里也包括静态实例方法,因为我们知道实例过程就是保存可以序列化的对象以及对象的状态

和信息,是将堆内存中的对象进行序列化而静态的变量属于类,并不属于某个对象

它存在于方法快中,所以静态的属性是不会被序列化的。

7. 如果一个对象的成员变量是一个对象的话,那么这个成员对象会被序列化的保存。


8. 如果一个可以序列化的对象中包含不可以序列化的对象的时候,那么整个序列化操作都会失败,

并且会抛出NotSerializableException ,不过我们可以将这个不可序列化的成员对象用transient关键字

修饰,那么对象还可以继续序列化的


9. 假如我们中序列化某个对象的时候,如果我们不想把他的某个非静态出现序列化时,

我们可以在它的声明类前面用transient关键字修饰,这样就可以不序列化这个属性了,那,这个属性依然存在于堆内存中。


10、如果我们有一个呗序列化完成的对象,我们又去修改了这个对象对应类的信息,如果将某个属性的修饰符从

default权限修改成private,或者添加一个属性,然后编译这个类,我们发现再去进行反序列化的时候,会有一个机制在运行,

序列化时,使用一个称为serialVersionUID的版本号与每个可序列化类相关联,该序列化在反序列化过程

中用于验证序列化对象的发送者和接收者是否为该对象加载了与序列化兼容的类。如果接收者加载的该对象的

serialVersionUID与对应的发送者的标识号不同,则反序列化将发生InvalidClassException

所以序列化时UID和序列化后的UID发生改变,不匹配,就报错


如果我们不希望因为这样的一些修改导致无法反序列化,我们就可以在该对象类中添加一个特有的属性

long类型的常量来固定这个UID,这样后续不管如何修改类的信息,反序列化时都可以正常运行。


ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;

修饰符可以任意修改都可以被反序列化。


11.序列化和反序列化的几个主要的类:

a.因为序列化是将某个对象保存到存储设备上,实现对象的持久化,所以我们当然要给它创建目的地

所以要使用FileOutputStream, 当然要使用它的带岑参的构造方法,同理反序列化也是需要通过流对象读取并还原

某个对象。


序列化:ObjectOutputStream(outputStream out);

反序列化:ObjectInputStream(InputStream in);


代码练习:

/*对象序列化对象序列化    对象序列化对象序列化ObjectInputSStream 类构造方法摘要 protected  ObjectInputStream()           为完全重新实现 ObjectInputStream 的子类提供一种方式,让它不必分配仅由 ObjectInputStream 的实现使用的私有数据。   ObjectInputStream(InputStream in)           创建从指定 InputStream 读取的 ObjectInputStream。  void writeObject(Object obj)           将指定的对象写入 ObjectOutputStream。 ObjectOutputStream  类构造方法摘要 protected  ObjectOutputStream()           为完全重新实现 ObjectOutputStream 的子类提供一种方法,让它不必分配仅由 ObjectOutputStream 的实现使用的私有数据。   ObjectOutputStream(OutputStream out)           创建写入指定 OutputStream 的 ObjectOutputStream 注意:要被序列化的对象需要实现IO包中   ,Serializable接口(是一个标记接口,没有方法)固定标记:ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;  异常:NotSerializableException   对象中的静态成员和被transient 关键字修饰的成员,是不能被序列化的  */  import java.io.*;class SerializableDemo{public static void main(String[] args)throws Exception{//writeObj();readObj();}//对象的序列化操作public static void writeObj()throws IOException{ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("G:\\IO\\其他流\\SplitFile\\序列化.txt"));oos.writeObject(new Person("heima",25,"USA"));oos.close();}//对象的反序列化操作public static void readObj()throws Exception{ObjectInputStream ois=new ObjectInputStream(new FileInputStream("G:\\IO\\其他流\\SplitFile\\序列化.txt"));Person p=(Person)ois.readObject();System.out.println(p);ois.close();}}class Person implements Serializable{String name;int age;static String county="ch";final long serialcersionUID=42L;//固定UIDPerson(String name,int age,String county){this.name=name;this.age=age;this.county=county;}public String getName(){return name;}public int getAge(){return age;}public String getCounty(){return county;}public String toString(){return getName()+"---"+getAge()+"--"+getCounty();}}















---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------