本系列博客汇总在这里:Java系列_汇总
目录
一、简介
-
把对象以流的形式存储在硬盘上或者数据库中的过程就是写序列化流,读取的过程就是反序列化。
-
序列化流
(1)对象输出流:ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream。
(2)对象输入流:ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。
1、ObjectOutputStream 的构造器
2、ObjectInputStream 的构造器
(1)如果想序列化某个对象,那么这个对象所对应的类必须实现 java.io.Serializable 接口以启用其序列化功能,在序列化的过程中要手动指定要序列化的类的的 serialVersionUID,这样可以在类改变后依然可以反序列化,否则会报错。
(2)要想对一个类的对象实现序列化就必须实现Serializable接口,默认情况下如果使用了这个类做过的序列化,在修改类之后再做反序列化就出现类的序列化版本不一致的情况,如下图:
解决: 我们手动指定类的序列化的版本,再次改变类的时候就不会出错了。
二、序列化对象的写入(序列化)
- 示例源码
public class Person implements Serializable { /** * 指定一个指定的序列化版本的ID,如果这个类发生了改变不会影响反序列化 */ private static final long serialVersionUID = -3050521367627600292L; private String name; private int 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; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
public static void main(String[] args) { ObjectOutputStream out = null; try { // 创建序列化流的对象 out = new ObjectOutputStream(new FileOutputStream("e.txt")); Person p = new Person(); p.setName("张三"); p.setAge(23); // 把对象写入文件(序列化) out.writeObject(p); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (out != null) out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
二、序列化对象的读取(反序列化)
- 示例
public static void main(String[] args) { ObjectInputStream in = null; try { //创建序列化流的对象 in = new ObjectInputStream(new FileInputStream("e.txt")); //从序列化流中读取数据(反序列化) Object obj = in.readObject(); Person p = (Person) obj; System.out.println(p.getName() + " " + p.getAge()); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { if (in != null) in.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
三、集合序列化
实际工作中,我们不可能一个一个依次下代码写入,这是不现实的。
1、使用集合序列化写入对象
- 示例
public static void main(String[] args) { ObjectOutputStream out = null; try { List<Person> pList = new ArrayList<Person>(); // 创建序列化流的对象 out = new ObjectOutputStream(new FileOutputStream("e.txt")); for (int i = 0; i < 10; i++) { Person p = new Person(); p.setName("张三" + i); p.setAge(23 + i); pList.add(p); } // 把集合序列化 out.writeObject(pList); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { try { if (out != null) out.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2、读取序列化文件
- 示例
public static void main(String[] args) { ObjectInputStream in = null; try { // 创建序列化流的对象 in = new ObjectInputStream(new FileInputStream("e.txt")); // 读取序列化文件(反序列化) Object obj = in.readObject(); List<Person> pList = (List<Person>) obj; for (Person p : pList) { System.out.println(p); } } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { try { if (in != null) in.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
如有错误,欢迎指正!