首页 > 代码库 > 对象流

对象流

ObjectInputStream 和 OjbectOutputSteam
用于存储和读取对象的处理流。
它的强大之处就是可以把 Java 中的对象写入到数据源中,也能把对象从数据源中还原回来。

序列化( Serialize ):用 ObjectOutputStream 类将一个 Java 对象写入 IO 流中
反序列化( Deserialize ):用 ObjectInputStream 类从 IO 流中恢复该 Java 对象
ObjectOutputStream 和 ObjectInputStream 不能序列化 static transient 修饰的成员变量(但是可以运行,只是该成员变量读出来是 null )

对象序列化机制允许把内存中的 Java 对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点,当其它程序获取了这种二进制流,就可以恢复成原来的 Java 对象

序列化的好处在于可将任何实现了 Serializable 接口的对象转化为字节数据,使其在保存和传输时可被还原

序列化是 RMIRemote Method Invoke远程方法调用)过程的参数和返回值都必须实现的机制,而 RMI JavaEE 的基础。因此序列化机制是 JavaEE 平台的基础

如果需要让某个对象支持序列化机制,则必须让其类及其成员变量均是可序列化的,为了让某个类是可序列化的,该类必须实现如下两个接口之一:Serializable、Externalizable( Serializable 的子类)

凡是实现 Serializable 接口的类都有一个表示序列化版本标识符的静态变量用来表明类的不同版本间的兼容性
private static final long serialVersionUID;
如果类没有显式定义这个静态变量,它的值是 Java 运行时环境根据类的内部细节自动生成
若类的源代码作了修改,serialVersionUID 可能发生变化,故建议,显式声明

显式定义 serialVersionUID 的用途
希望类的不同版本对序列化兼容,因此需确保类的不同版本具有相同的 serialVersionUID
希望类的不同版本对序列化兼容,因此需确保类的不同版本具有不同的 serialVersionUID

序列化
创建一个 ObjectOutputStream
调用 ObjectOutputStream 对象的 writeObject(对象) 方法输出可序列化对象
注意每次写出都操作一遍 flush()

反序列化
创建一个 ObjectInputStream
调用 readObject() 方法读取流中的对象

注意:如果某个类的字段不是基本数据类型或 String  类型,而是另一个引用类型,那么这个引用类型必须是可序列化的,否则拥有该类型的 Field 的类也不能序列化

举例:
  1. @Test
  2. public void testOut() {
  3. ObjectOutputStream oos = null;
  4. try {
  5. oos = new ObjectOutputStream(new FileOutputStream("Person.txt"));
  6. Person p = new Person(23, "chen", new Pet("2", "dog"));
  7. oos.writeObject(p);
  8. } catch (SecurityException e) {
  9. e.printStackTrace();
  10. } catch (FileNotFoundException e) {
  11. e.printStackTrace();
  12. } catch (IOException e) {
  13. e.printStackTrace();
  14. } finally {
  15. try {
  16. if (oos != null) {
  17. oos.close();
  18. }
  19. } catch (IOException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. }
  24. @Test
  25. public void testIn() {
  26. ObjectInputStream ois = null;
  27. try {
  28. ois = new ObjectInputStream(new FileInputStream("Person.txt"));
  29. Person p = (Person) ois.readObject();
  30. System.out.println(p);
  31. } catch (FileNotFoundException e) {
  32. e.printStackTrace();
  33. } catch (ClassNotFoundException e) {
  34. e.printStackTrace();
  35. } catch (IOException e) {
  36. e.printStackTrace();
  37. } finally {
  38. if (ois != null) {
  39. try {
  40. ois.close();
  41. } catch (IOException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. }
  46. }
  47. }
  48. class Person implements Serializable {
  49. public static final long serialVersionUID = 1L;
  50. Integer age;
  51. String name;
  52. Pet pet;
  53. public Person(Integer age, String name, Pet pet) {
  54. super();
  55. this.age = age;
  56. this.name = name;
  57. this.pet = pet;
  58. }
  59. @Override
  60. public String toString() {
  61. return "Person [age=" + age + ", name=" + name + ", pet=" + pet + "]";
  62. }
  63. }
  64. class Pet implements Serializable {
  65. public static final long serialVersionUID = 2L;
  66. String name;
  67. String kind;
  68. public Pet(String name, String kind) {
  69. super();
  70. this.name = name;
  71. this.kind = kind;
  72. }
  73. @Override
  74. public String toString() {
  75. return "Pet [name=" + name + ", kind=" + kind + "]";
  76. }

对象流