Java 序列化相关

来源:互联网 发布:淘宝发布宝贝教程图解 编辑:程序博客网 时间:2024/05/22 04:46

Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java对象序列化就能够帮助我们实现该功能。

1、什么是序列化和反序列化
Serialization(序列化)是一种将对象以一连串的字节描述的过程;反序列化deserialization是一种将这些字节重建成一个对象的过程。


2、什么情况下需要序列化 
a)当你想把的内存中的对象保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI(远程方法调用)传输对象的时候;

3、如何实现序列化

将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个类可以序列化。

如果我们想要序列化一个对象,首先要创建某些OutputStream(如FileOutputStream、ByteArrayOutputStream等),然后将这些OutputStream封装在一个ObjectOutputStream中。这时候,只需要调用writeObject()方法就可以将对象序列化,并将其发送给OutputStream(记住:对象的序列化是基于字节的,不能使用Reader和Writer等基于字符的层次结构)。而反序列的过程(即将一个序列还原成为一个对象),需要将一个InputStream(如FileInputstream、ByteArrayInputStream等)封装在ObjectInputStream内,然后调用readObject()即可。


这里Override的toString 是所有 Object 的对象都有的方法,Serializable 接口里没有方法,它会生成一个类型为 long 的序列号,这个是关键的不同。


enum Gender {      MALE, FEMALE  } class Person implements Serializable {      private String name = null;       private Integer age = null;       private Gender gender = null;       public Person() {          System.out.println("none-arg constructor");      }       public Person(String name, Integer age, Gender gender) {          System.out.println("arg constructor");          this.name = name;          this.age = age;          this.gender = gender;      }        @Override     public String toString() {          return "[" + name + ", " + age + ", " + gender + "]";      }  } public class TestSerialize {    public static void main(String[] args) throws Exception {          File file = new File("C://Temp//person.txt");           ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream(file));          Person person = new Person("John", 22, Gender.MALE);          oout.writeObject(person);          oout.close();           ObjectInputStream oin = new ObjectInputStream(new FileInputStream(file));          Object newPerson = oin.readObject(); // 没有强制转换到Person类型          oin.close();          System.out.println(newPerson);      }  }

上述程序的输出的结果为:

  1. arg constructor  
  2. [John, 31, MALE] 

transient关键字

当某个字段被声明为transient后,默认序列化机制就会忽略该字段。此处将Person类中的age字段声明为transient,如下所示,

  1. public class Person implements Serializable {  
  2.     ...  
  3.     transient private Integer age = null;  
  4.     ...  

再执行SimpleSerial应用程序,会有如下输出:

  1. arg constructor  
  2. [John, null, MALE] 


总结:

a)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;

b)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;

c) static,transient后的变量不能被序列化;

http://www.2cto.com/kf/201405/305380.html

http://developer.51cto.com/art/201202/317181.htm

0 0
原创粉丝点击