对象的序列化和反序列化

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

22,ObjectInputStreamObjectOutputStream

22.1对象的序列化流和反序列化流

这两个流对象是用来操作对象的。

对象的序列化:就是让对象中封装的数据可以持久化存储。

对象的反序列化:就是通过存储的文件数据获取对象实体。

对象序列化的条件:

必须要实现Serializable接口,否则无法实现对象的序列化。此接口提供了一个serialVersionUID,用于验证序列化和反序列化时是否是同一个对象,如果不是则无法反列化。

ObjectInputStreamObjectOutputStream都是装饰类,用于增强流对象的功能。

其构造函数:

ObjectInputStream(InputStream out)

ObjectOutputStream(OutputStream out)

分别都接收一个字节流。

22.2对象的序列化

用到的流对象是:ObjectOutputStream 

使用其方法:writerObject(被序列化的对象);

多个对象,就多次调用writerObject().

注意:对象的序列化,只存储对象中非瞬态和非静态的字段。

如:

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectOutputStream;

import java.io.Serializable;

public class ObjectOutputStream Demo {

      public static void main(String[] args)throws FileNotFoundException, IOException {

             //创建对象序列化流,将对象的数据保存在,指定的文件中。

             ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:\\person.object"));

             //序列化对象。

             oos.writeObject(new Person("李四",44));

             //关闭资源

             oos.close();

      }
}

class Person implements Serializable{//对象要序列化必须要实现此接口

      private String name;
     private int age;
      public Person(String name,int age) {

             super();

             this.name = name;

             this.age = age;

      }

      public String getName() {

             return name;

      }

      public void setName(String name) {

             this.name = name;

      }

      public int getAge() {

             return age;

      }

      public void setAge(int age) {

             this.age = age;

      }

 }


22.3对象的反序列化

对象的反序列化使用流对象:ObjectInputStream

使用方法:readObject();此方法返回Object对象,需要进行强转。

多个对象被反序列化,就多次调用readObject()每次读取一个对象。

通过读取被序列化对象的文件,获取对象。

如:

import java.io.FileInputStream;

import java.io.FileNotFoundException;

importjava.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

importjava.io.ObjectOutputStream;

import java.io.Serializable;

public class ObjectOutputStream Demo {

       public static void main(String[] args)throws ClassNotFoundException, FileNotFoundException, IOException {

             //创建对象序列化流,将对象的数据保存在,指定的文件中。

             ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\person.object"));

             //反序列化对象。

             Person p=(Person)ois.readObject();

             System.out.println(p.getName()+"::"+p.getAge());

             //关闭资源

             ois.close();
      }
}

/*

 *打印结果:李四::44

 */


 

通过反序列化流,可以从一个存储对象数据的文件中获取这个对象,实现了对象数据的持久化存储和对象的获取。

注意:对象反序列化时要获取对象,必须要满足:

1,            有对象的序列化文件。

2,            要有对象所属的字节码文件。否则,无法获取对象。

 

 

如果一个对象被序列化后,其原有的数据被修改,这时就不能完成反序列化。

异常信息:

Exception in thread "main"java.io.InvalidClassException: IO.Person; local class incompatible: stream classdesc serialVersionUID = -5252691168862610579, local class serialVersionUID = -7585441751578431892

 

这是因为serialVersionUID号不一致造成的,对象的反序列化过程中,会检查这个版本号与原对象的版本号是否一致,如果不一致就无法完成反序化,serialVersionUID在类中如果没有明确声明的情况下,会根据类中的内容默认计算出一个,当然,也可在类中自己声明一个serialVersionUID,不管类中数据是否变化,只要此号不变,就可以完成反序列化。

如:

class Person implements Serializable{//对象要序列化必须要实现此接口

      private static final long serialVersionUID = 1L;//显示声明serialVersionUID

      private int age;

      private String name;

      public Person(String name,int age) {

             super();

             this.name = name;

             this.age = age;

      }

      public String getName() {

             return name;

      }

      public void setName(String name) {

             this.name = name;

      }

      public int getAge() {

             return age;

      }

      public void setAge(int age) {

             this.age = age;
      }
}

22.4关键字 transient(瞬态)

对象的序列化,其静态和非瞬态的字段是不能被存储到文件中的。

如果一个字段不是静态,但也不想被存储到文件中,就可以加上此关键字:transient

如:

import java.io.FileInputStream;

import java.io.FileNotFoundException;

importjava.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

importjava.io.ObjectOutputStream;

import java.io.Serializable;

public class ObjectOutputStreamDemo {

      public static void main(String[] args)throws ClassNotFoundException, FileNotFoundException, IOException {

             //创建对象序列化流,将对象的数据保存在,指定的文件中。

             ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\person.object"));

             //反序列化对象

             Person p=(Person)ois.readObject();

             System.out.println(p.getName()+"::"+p.getAge());

             //关闭资源

             ois.close();

      }
}

class Personimplements Serializable{//对象要序列化必须要实现此接口

      private static final long serialVersionUID = 1L;//显示声明serialVersionUID

      private static int age;//静态属性

      private transient String name;//瞬态属性

      public Person(String name,int age) {

             super();

             this.name = name;

             this.age = age;

      }

      public String getName() {

             return name;

      }

      public void setName(String name) {

             this.name = name;

      }

      public int getAge() {

             return age;

      }

      public void setAge(int age) {

             this.age = age;

      }

}

/*

 *反序列化打印结果:null::0

 */


 

注意:多个对象的序列化,就多次调用writeObject(),多个对象的反序列化就多次调用readObject(),有几个对象就读取几个。

import java.io.FileInputStream;

import java.io.FileNotFoundException;

importjava.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

importjava.io.ObjectOutputStream;

import java.io.Serializable;

 

public class ObjectOutputStream Demo {

      public static void main(String[] args)throws ClassNotFoundException, FileNotFoundException, IOException {

//           ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:\\person.object"));

             //序列化多个对象

//           oos.writeObject(new Person("李四",33));

//           oos.writeObject(new Person("张三",24));

//           oos.writeObject(new Person("小强",45));

//           oos.writeObject(new Person("李明",23));

//           oos.close();

             

             //创建对象序列化流,将对象的数据保存在,指定的文件中。

             ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:\\person.object"));

             //反序列化多个对象。

             Person p1=(Person)ois.readObject();

             Person p2=(Person)ois.readObject();

             Person p3=(Person)ois.readObject();

             Person p4=(Person)ois.readObject();

             System.out.println(p1.getName()+"::"+p1.getAge());

             System.out.println(p2.getName()+"::"+p2.getAge());

             System.out.println(p3.getName()+"::"+p3.getAge());

             System.out.println(p4.getName()+"::"+p4.getAge());

             //关闭资源

             ois.close();
      }
}

class Person implements Serializable{//对象要序列化必须要实现此接口

 

      private static final long serialVersionUID = 1L;//显示声明serialVersionUID

      private int age;

      private String name;

      public Person(String name,int age) {

             super();

             this.name = name;

             this.age = age;

      }

      public String getName() {

             return name;

      }

      publicvoid setName(String name) {

             this.name = name;

      }

      publicint getAge() {

             return age;

      }

      publicvoid setAge(int age) {

             this.age = age;
      }
}

 

/*

 *打印结果:

李四::33

张三::24

小强::45

李明::23

 */


 

总结:对象的序列化和反序列化可以将对象持久保存,并可以随时获取对象,实现了对象中数据的持久保存。对象要序列化必须要实现Serializable接口,并声明serialVersionUID号,以免反序列化时抛出异常。对象反序列化要获取对象,首先必须有保存对象的文件,其实,必须有对象所属的字节码文件。对象中的静态字段和transient修饰的字段是不能被序列化到文件中的。

 

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值