①作用:用于存储和读取基本数据类型或对象的处理流,可以把java对象写入到数据源,也能把对象从数据源还原出来
*②对象序列机制:允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。//当其它程序获取了这种二进制流,就可以恢复成原来的Java对象(面试可能会问) (简而言之:对象–>二进制流 永久存储 )
以下是代码展示,其中ObjectOutputStream是序列化过程,ObjectInputStream是反序列化过程。
public class ObjectInputOutputStreamTest { /* 序列化过程:将内存中的java对象保存在磁盘中或通过网络传输出去 使用ObjectOutputStream实现 */ @Test public void testObjectOutputStream(){ ObjectOutputStream oos = null; try { //dat文件,可以以多种方式打开(如.txt) oos = new ObjectOutputStream(new FileOutputStream("object.dat")); oos.writeObject(new String("hello!")); //每一次进行存储操作,必须要进行flush操作 oos.flush();//刷新操作 } catch (IOException e) { e.printStackTrace(); } finally { if (oos!=null) { try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* 反序列化:将磁盘文件中的对象还原为内存层面的一个java对象 */ @Test public void testObjectInputStream(){ ObjectInputStream ois=null; try { //读取哪个文件(文件要存在) ois = new ObjectInputStream(new FileInputStream("Object.dat")); //读取对象操作 Object obj = ois.readObject(); //类型强转 String str=(String) obj; System.out.println(str); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (ois!=null) { try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } } }序列化结果
反序列化结果 hello!
当序列化操作时存储的对象不是String类型,而是一个类对象(如Person),则应该将该类声明为可序列化的
定义一个Person类,可序列化操作:继承Serializable接口(通常情况)
import java.io.Serializable; /** * Person需要满足如下的需求,方可序列化 * 1、需要实现接口:Serializable * 2、需要当前类提供一个全局常量:serialVersionUID * * 补充:ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量,否则会丢失数据(可以自行演示) */ //注意该接口是一个“标识接口”,就是说里面不包含任何方法、变量等等 public class Person implements Serializable { //声明一个属性(必须要有,而该值可以自定义) public static final long serialVersionUID = 42165156L; //public static final long serialVersionUID = 4216514438856L; private String name; private int age; private int id; public Person() { } public Person(String name, int age, int id) { this.name = name; this.age = age; this.id = id; } 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; } public int getId() { return id; } public void setId(int id) { this.id = id; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", id=" + id + '}'; } }然后就是对象流的使用,跟前面的代码差不多,只不过我们存储了一个Person对象,则需要将Person定义为可序列化的
public class ObjectInputOutputStreamTest { /* 序列化过程:将内存中的java对象保存在磁盘中或通过网络传输出去 使用ObjectOutputStream实现 */ @Test public void testObjectOutputStream(){ ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new FileOutputStream("object.dat")); oos.writeObject(new String("hello!")); oos.flush();//刷新操作 //类对象 oos.writeObject(new Person("王明",23,1001)); oos.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (oos!=null) { try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /* 反序列化:将磁盘文件中的对象还原为内存层面的一个java对象 */ @Test public void testObjectInputStream(){ ObjectInputStream ois=null; try { ois = new ObjectInputStream(new FileInputStream("Object.dat")); Object obj = ois.readObject(); String str=(String) obj; //类型强转 Person p=(Person)ois.readObject(); System.out.println(str); System.out.println(p); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (ois!=null) { try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } } } }结果: hello! Person{name=‘王明’, age=23, id=1001}
类(如Person)的所有属性都必须是可序列化的,如果Person类里面有一个类对象(如图),则应该将该类也声明为可序列化的
(继承Serializable,定义全局变量public static final long serialVersionUID)