序列化流(ObjectOutputStream、ObjectInputStream)
1、序列化流(ObjectOutputStream)
1 package demo10.objstream; 2 3 /* 4 java.io.ObjectOutputStream extends OutputStream 5 ObjectOutputStream:对象的序列化流 6 作用:把对象以流的方式写入到文件中保存 7 8 构造方法: 9 ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。 10 参数: 11 OutputStream out:字节输出流 12 特有的成员方法: 13 void writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。 14 15 使用步骤: 16 1.创建ObjectOutputStream对象,构造方法中传递字节输出流 17 2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中 18 3.释放资源 19 */ 20 21 import java.io.FileNotFoundException; 22 import java.io.FileOutputStream; 23 import java.io.IOException; 24 import java.io.ObjectOutputStream; 25 26 public class demo01objout { 27 public static void main(String[] args) throws IOException { 28 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt")); 29 Person p=new Person("kelvin",18); 30 oos.writeObject(p); 31 oos.close(); 32 } 33 }
2、反序列化流(ObjectInputStream)
1 package demo10.objstream; 2 3 /* 4 java.io.ObjectInputStream extends InputStream 5 ObjectInputStream:对象的反序列化流 6 作用:把文件中保存的对象,以流的方式读取出来使用 7 8 构造方法: 9 ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。 10 参数: 11 InputStream in:字节输入流 12 特有的成员方法: 13 Object readObject() 从 ObjectInputStream 读取对象。 14 15 使用步骤: 16 1.创建ObjectInputStream对象,构造方法中传递字节输入流 17 2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件 18 3.释放资源 19 4.使用读取出来的对象(打印) 20 21 readObject方法声明抛出了ClassNotFoundException(class文件找不到异常) 22 当不存在对象的class文件时抛出此异常 23 反序列化的前提: 24 1.类必须实现Serializable 25 2.必须存在类对应的class文件 26 */ 27 28 import java.io.*; 29 30 public class demo01objin { 31 public static void main(String[] args) throws IOException, ClassNotFoundException { 32 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt")); 33 Object o = ois.readObject(); 34 ois.close(); 35 Person p = (Person) o; 36 System.out.println(p.getName() + " " + p.getAge()); 37 } 38 }
Person类
1 package demo10.objstream; 2 3 import java.io.Serializable; 4 5 /* 6 序列化和反序列化的时候,会抛出NotSerializableException没有序列化异常 7 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。 8 Serializable接口也叫标记型接口 9 要进行序列化和反序列化的类必须实现Serializable接口,就会给类添加一个标记 10 当我们进行序列化和反序列化的时候,就会检测类上是否有这个标记 11 有:就可以序列化和反序列化 12 没有:就会抛出 NotSerializableException异常 13 14 15 static关键字:静态关键字 16 静态优先于非静态加载到内存中(静态优先于对象进入到内存中) 17 被static修饰的成员变量不能被序列化的,序列化的都是对象 18 private static int age; 19 oos.writeObject(new Person("kelvin",18)); 20 Object o = ois.readObject(); 21 Person{name='kelvin', age=0} 22 23 transient关键字:瞬态关键字 24 被transient修饰成员变量,不能被序列化 25 private transient int age; 26 oos.writeObject(new Person("kelvin",18)); 27 Object o = ois.readObject(); 28 Person{name='kelvin', age=0} 29 30 */ 31 32 public class Person implements Serializable { 33 private String name; 34 private int age; 35 36 public Person() { 37 } 38 39 public Person(String name, int age) { 40 this.name = name; 41 this.age = age; 42 } 43 44 @Override 45 public String toString() { 46 return "Person{" + 47 "name='" + name + '\'' + 48 ", age=" + age + 49 '}'; 50 } 51 52 public String getName() { 53 return name; 54 } 55 56 public void setName(String name) { 57 this.name = name; 58 } 59 60 public void setAge(int age) { 61 this.age = age; 62 } 63 64 public int getAge() { 65 return age; 66 } 67 }
# 注:在序列化对象时,由于该对象所属的类实现了Serializable接口,所以该类在编译时会在.class文件中保存SerialVersionUID=xxx标识,如果类定义发生改变,SerialVersionUID也会改变。并且序列化对象时,内部会携带该标识,当反序列化时候,判断如果反序列化的对象内部的SerialVersionUID和.class文件内部保存的SerialVersionUID相同反序列化成功,否则抛出InvalidClassException异常。 解决方式: 在定义类时候手动定义SerialVersionUID。 格式为:private static final long serialVersionUID=xxL
3、练习(序列化集合)
1 package demo10.objstream; 2 3 import java.io.*; 4 import java.util.ArrayList; 5 6 public class test { 7 public static void main(String[] args) throws IOException, ClassNotFoundException { 8 // output(); 9 input(); 10 } 11 12 private static void input() throws IOException, ClassNotFoundException { 13 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("list.txt")); 14 Object o = ois.readObject(); 15 ArrayList<Person> list = (ArrayList) o; 16 for (Person person : list) { 17 System.out.println(person); 18 } 19 ois.close(); 20 21 } 22 23 private static void output() throws IOException { 24 ArrayList<Person> list = new ArrayList<>(); 25 list.add(new Person("kelvin", 23)); 26 list.add(new Person("jack", 18)); 27 list.add(new Person("siri", 34)); 28 29 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt")); 30 oos.writeObject(list); 31 oos.close(); 32 } 33 }