分享

java se序列化和反序列化

 昵称9918558 2012-05-08

首先要明白什么是序列化和反序列化。

所谓的序列化就是要告诉计算机如何的对某一个对象进行存储;相反,反序列化也就是告诉计算机如何的读取某个对象。

java中,序列化、反序列化很简单就是要实现Serializable这个接口,然而这个接口中没有任何的方法,也就是说它只是一个标识性接口,就像annotation一样,只是告诉编译器这个类的对象是可以被序列化和反序列化的,当然,编译器也会根据这个信息去序列化或者反序列化该对象。那么序列化该对象的方法就是通过ObjectOutputStream流中的writeObject方法将一个对象去序列化一个对象;反序列化就是通过ObjectInputStream中的readObject方法。

那么序列化和反序列化有什么作用呢?

根据我个人的理解:序列化就是将一个对象的完整信息长久的存储到一个地方,以方便对象的保存、传递等。反序列化就是读取序列化后的信息。

那么了解一下官方的解释:

1、以某种存储形式使自定义对象持久化;

2、将对象从一个地方传递到另一个地方。

3、使程序更具维护性

 

接下来了解一下,哪一些内容是在序列化的范围之内的。

序列化就是要保存一些非静态的信息。其实显而易见,静态的信息都是类本身所具有的属性,没有必要将其序列化,当我们将序列化后的信息进行反序列化时,当然也需要转换为实际对应的类了,那么那些静态的信息属于类本身的,就不需要我们的转换了,那就不需要我们转换了,自然就不需要序列化了。

那么看一下官方的解释吧:

对象的默认序列化机制写入的内容是:对象的类,类签名,以及非瞬态和非静态字段的值。其他对象的引用(瞬态和静态字段除外)也会导致写入那些对象。可使用引用共享机制对单个对象的多个引用进行编码,这样即可将对象的图形恢复为最初写入它们时的形状。 

 

 

下面来看一些实例吧:

下面两个简单的类,很容易看明白:

package dong.application.serialization;

 

import java.io.Serializable;

 

public class Person implements Serializable

{

       privateString name;

       privateString address;

       privateint age;

       

       publicPerson(String name, String address, int age)

       {

              this.name= name;

              this.address= address;

              this.age= age;

       }

 

       publicString getName()

       {

              returnname;

       }

 

       publicvoid setName(String name)

       {

              this.name= name;

       }

 

       publicString getAddress()

       {

              returnaddress;

       }

 

       publicvoid setAddress(String address)

       {

              this.address= address;

       }

 

       publicint getAge()

       {

              returnage;

       }

 

       publicvoid setAge(int age)

       {

              this.age= age;

       }

       

       @Override

       publicString toString()

       {

              return"name:" + name + " address:" + address + " age:"+ age;

       }

}

 

 

 

package dong.application.serialization;

 

import java.io.Serializable;

 

public class Company implementsSerializable

{

       privatePerson person;

       

       privateString department;

       

       publicCompany(Person person, String department)

       {

              this.person= person;

              this.department = department;

       }

 

       publicPerson getPerson()

       {

              returnperson;

       }

 

       publicvoid setPerson(Person person)

       {

              this.person= person;

       }

 

       publicString getDepartment()

       {

              returndepartment;

       }

 

       publicvoid setDepartment(String department)

       {

              this.department= department;

       }

}

 

 

下面开始测试

package dong.application.serialization;

 

import java.io.EOFException;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

 

public class SerializationTest

{

       publicstatic void main(String[] args) throws Exception

       {

              seriableObject();

              unSeriableObject();

       }

 

       privatestatic void seriableObject() throws FileNotFoundException,

                     IOException

       {

              Personp1 = new Person("dong", "henan",22);

              Personp2 = new Person("jing", "shenzhen", 21);

              Companyc1 = new Company(p1, "jishubu");

              Companyc2 = new Company(p2, "aiqingbu");

              FileOutputStreamfos = new FileOutputStream("love.txt");

              ObjectOutputStreamoos = new ObjectOutputStream(fos);

              oos.writeObject(c1);

              oos.writeObject(c2);

              oos.close();

              fos.close();

       }

       privatestatic void unSeriableObject() throws IOException,

                     ClassNotFoundException

       {

              FileInputStreamfis = new FileInputStream("love.txt");

              ObjectInputStreamois = new ObjectInputStream(fis);

              Companycompany = null;

              try

              {

                     do

                     {

                            company= (Company) ois.readObject();

 

                            System.out.println("department:"+ company.getDepartment()

                                          +"person:" + company.getPerson());

                     }while (true);

              }

              catch(EOFException eof)

              {

              }

              ois.close();

              fis.close();

       }

}

 

结果:

department:jishubuperson:name:dong address:henan age:22

department:aiqingbuperson:name:jing address:shenzhenage:21

 

 

那么我们是否可以定义自己的序列化方法呢?

答案是肯定的。只要我们在实现序列化的类中添加如下两个方法即可:

private void writeObject(java.io.ObjectOutputStream out)

     throws IOException

 private voidreadObject(java.io.ObjectInputStream in)

     throws IOException, ClassNotFoundException;

 private void readObjectNoData() 

     throwsObjectStreamException;

在这两个方法中,需要自定义自己所需要存储的东西,你存储什么,那么它就会序列化什么,那么在反序列化的时候就会按照你定义的readObject方法进行反序列化,要注意:你序列化的顺序应该和反序列化的顺序一样。那样才能正确读取你序列化的内容。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多