序列化
概述
Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据
、对象的类型
和对象中存储的属性
等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。
反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据
、对象的类型
和对象中存储的数据
信息,都可以用来在内存中创建对象。看图理解序列化:
ObjectOutputStream类
java.io.ObjectOutputStream
类,将Java对象的原始数据类型写出到文件,实现对象的持久存储。
构造方法
-
public ObjectOutputStream(OutputStream out)
: 创建一个指定OutputStream的ObjectOutputStream。
序列化操作
- 一个对象要想序列化,必须满足两个条件:
- 该类必须实现
java.io.Serializable
接口,Serializable
是一个标记接口,不实现此接口的类将不会使任何状态序列化或反序列化,会抛出NotSerializableException
。 - 该类的所有属性必须是可序列化的。如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,使用
transient
关键字修饰。
2.写出对象方法
-
public final void writeObject (Object obj)
: 将指定的对象写出。
ObjectInputStream类
ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。
构造方法
-
public ObjectInputStream(InputStream in)
: 创建一个指定InputStream的ObjectInputStream。
反序列化操作1
如果能找到一个对象的class文件,我们可以进行反序列化操作,调用ObjectInputStream
读取对象的方法:
-
public final Object readObject ()
: 读取一个对象。
对于JVM可以反序列化对象,它必须是能够找到class文件的类。如果找不到该类的class文件,则抛出一个 ClassNotFoundException
异常。
反序列化操作2
另外,当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改,那么反序列化操作也会失败,抛出一个InvalidClassException
异常。发生这个异常的原因如下:
- 该类的序列版本号与从流中读取的类描述符的版本号不匹配
- 该类包含未知数据类型
- 该类没有可访问的无参数构造方法
序列化实现
被序列化类: 想要被 序列化,需要实现 Serializable
接口。假如,有属性不需要被序列化,需要加上 瞬态关键字transient
关键字
public class 被序列化类 implements Serializable {
public String love;
public transient String name;
public int age;
public void show(){
System.out.println("mylove="+love+"---myname="+name+"---myage="+age);
}
}
使序列化:
public class 使序列化 {
public static void main(String[] args) {
被序列化类 u=new 被序列化类();
u.name="张三";
u.love="钓鱼";
u.age=89;
try {
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("D:\\夏季的笔记的消息\\图片\\寒假图片\\实验性的文件夹\\IO\\序列文件.txt"));
out.writeObject(u);
out.close();
System.out.println("对象中除了name,其它都被序列化了");
} catch (IOException e) {
e.printStackTrace();
}
}
}
反序列化:
public class 反序列化 {
public static void main(String[] args) {
try {
ObjectInputStream in=new ObjectInputStream(new FileInputStream("D:\\夏季的笔记的消息\\图片\\寒假图片\\实验性的文件夹\\IO\\序列文件.txt"));
被序列化类 u=(被序列化类) in.readObject();
u.show();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}