首先要明白什么是序列化和反序列化。 所谓的序列化就是要告诉计算机如何的对某一个对象进行存储;相反,反序列化也就是告诉计算机如何的读取某个对象。 在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方法进行反序列化,要注意:你序列化的顺序应该和反序列化的顺序一样。那样才能正确读取你序列化的内容。 |
|