对象序列化基本概念

序列化的基本定义:将内存保存的数据以二进制数据流的形式进行处理,可以实现对象的保存或者网络传输。

Hession对象序列化 对象序列化描述_Hession对象序列化


而对象序列化一般都是计算机处理的,用户只做标记。

并不是所有对象都可以进行序列化,强制性要求:需要序列化的类需要实现java.io.Serializable接口,作为序列化标记。

Serializable接口没有方法,他描述的是类的能力。
范例:定义一个可以序列化的类

@SuppressWarnings("serial")
class Person implements Serializable{
	private String name;
	private int age;
	public Person(String name,int age) {
		this.name=name;
		this.age=age;
	}
	public String toString() {
		return "名字:"+name+",年龄:"+age;
	}
}

此时Person类产生的对象都可以进行二进制传输,属于可以被序列化的程序类。

序列化与反序列化处理

有了序列化的支持类之后,如果想要实现序列化和反序列化的操作可以使用两个类:

  • 序列化:ObjectOutputStream
  • 类定义:public class ObjectOutputStream extends OutputStream implements ObjectOutput, ObjectStreamConstants
  • 构造方法:public ObjectOutputStream(OutputStream out) throws IOException
  • 操作方法1:public final void writeObject (Object obj) throws IOException
  • 反序列化:ObjectInputStream
  • 类定义:public class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants
  • 构造方法:public ObjectInputStream(InputStream in) throws IOException
  • 操作方法1:public final Object readObject()throws IOException,FileNotFoundException

范例:实现序列化与反序列化

import java.io.*;

public class SerializeTest {
	private static final File SAVE_FILE=new File("F:\\course\\Person");
	public static void main(String[] args) throws Exception {
		saveDate(new Person("妹妹",18));
		System.out.println(printDate());
	}
	public static void saveDate(Object obj) throws Exception {
		ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(SAVE_FILE));
		oos.writeObject(obj);//序列化
		oos.close();
	}
	public static Object printDate() throws Exception {
		ObjectInputStream ois=new ObjectInputStream(new FileInputStream(SAVE_FILE));
		Object obj=ois.readObject();//反序列化
		ois.close();
		return obj;
	}

}
@SuppressWarnings("serial")
class Person implements Serializable{
	private String name;
	private int age;
	public Person(String name,int age) {
		this.name=name;
		this.age=age;
	}
	public String toString() {
		return "名字:"+name+",年龄:"+age;
	}
}

java中序列化和反序列化必须使用内部提供的对象操作流,因为这里牵扯到二进制数据格式,所以不能自定义处理。如果想要使用一组对象序列化可以使用对象数组。
在开发过程中很少见到ObjectOutputStream,ObjectInputStream。会有一些容器帮助实现。更多关注Serializable接口。

transient关键字

默认情况下,当执行对象序列化时会将所有属性全部进行序列化处理。如果某些属性不需要序列化处理可以使用transient关键字进行标记。
public transient String name;此时name属性的内容是不会被保存下来的。换言之,读取的数据name是其对应数据类型的默认值(null)。
使用场景:如果类中有一些需要计算保存的属性内容,往往就不需要序列化。(例:单价,数量,总价)。(但开发过程中需要被序列化的类大多是简单java类,所以很少使用。)