【Java】对象的序列化与反序列化

1.如果要让类能够被序列化,就实现Serializable

import java.io.Serializable;

public class Person implements Serializable {

	private static final long serialVersionUID = 1L;

	private String name;
	private int age;
	private String phoneNumber;

	public Person() {
		this.name = "";
		this.age = 0;
		this.phoneNumber = "";
	}

	public Person(String name, int age, String phoneNumber) {
		this.name = name;
		this.age = age;
		this.phoneNumber = phoneNumber;
	}

	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 String getPhoneNumber() {
		return phoneNumber;
	}

	public void setPhoneNumber(String phoneNumber) {
		this.phoneNumber = phoneNumber;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", phoneNumber="
				+ phoneNumber + "]";
	}

}

2.将序列化对象写入文件

  • 创建FileOutputStream
  • 创建ObjectOutputStream
  • 写入对象
  • 关闭流

3.解序列化——从文件或流中读取序列化对象

  • 创建FileInputStream
  • 创建ObjectInputStream
  • 读取对象
  • 转换对象类型
  • 关闭流

4.程序实例

public class TestSerial {

	/**
	 * @param objectList
	 *            要序列化的实体集合
	 * @param fileName
	 *            保存实体的文件名
	 */
	public void writeSerialEntry(ArrayList<Person> objectList, String fileName) {
		FileOutputStream fileOutputStream;
		ObjectOutputStream objectOutputStream;
		try {
			fileOutputStream = new FileOutputStream(fileName);
			objectOutputStream = new ObjectOutputStream(fileOutputStream);

			objectOutputStream.writeInt(objectList.size());
			for (Object object : objectList) {
				objectOutputStream.writeObject(object);
			}

			fileOutputStream.close();
			objectOutputStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param fileName
	 *            读取存放实体信息的文件名
	 * @return 读取到的实体集合
	 */
	public ArrayList<Object> getSerialEntry(String fileName) {
		ArrayList<Object> objects = new ArrayList<Object>(6);

		FileInputStream fileInputStream;
		ObjectInputStream objectInputStream;
		try {
			fileInputStream = new FileInputStream(fileName);
			objectInputStream = new ObjectInputStream(fileInputStream);

			int length = objectInputStream.readInt();
			for (int i = 0; i < length; i++) {
				objects.add(objectInputStream.readObject());
			}

			fileInputStream.close();
			objectInputStream.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		return objects;
	}
}


测试程序

public class TestSerializableMain {

	// 创建几个要保存的实体信息
	public static ArrayList<Person> inputEntry() {
		ArrayList<Person> personList = new ArrayList<Person>();

		Person[] personArray = { new Person("Jhon", 23, "136005698701"),
				new Person("Green", 24, "136567698702"),
				new Person("Andy", 25, "136005698703"),
				new Person("White", 26, "136524698704"),
				new Person("Bush", 27, "132575698705"), };

		for (Person person : personArray) {
			personList.add(person);
		}

		return personList;
	}

	public static void main(String args[]) {
		final String fileName = "C:\\Users\\ht\\Desktop\\testSerial.ser";

		ArrayList<Person> personList = inputEntry();
		TestSerial testSerial = new TestSerial();
		testSerial.writeSerialEntry(personList, fileName);

		ArrayList<Object> result = testSerial.getSerialEntry(fileName);
		for (Object object : result) {
			Person person = (Person) object;

			System.out.println(person.toString());
		}
	}
}

5.serial Version UID

简单来说,Java的序列化机制是通过在运行时判断类的serial Version UID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serial Version UID与本地相应实体(类)的serial Version UID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。

当实现java.io.Serializable接口的实体(类)没有显式地定义一个名为serial Version UID且类型为long的变量时,Java序列化机制会根据编译的class自动生成一个serialVersionUID作序列化版本比较用,这种情况下,只有同一次编译生成的class才会生成相同的serial Version UID 。

如果我们不希望通过编译来强制划分软件版本,即实现序列化接口的实体能够兼容先前版本中未作更改的类,就需要显式地定义一个名为serial Version UID,类型为long的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值