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的变量,不修改这个变量值的序列化实体都可以相互进行串行化和反串行化。