1.概念
序列化:把对象转换为字节序列的过程称为对象的序列化。反序列化:把字节序列恢复为对象的过程称为对象的反序列化
2.什么情况下需要序列化
- 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
- 当你想用套接字在网络上传送对象的时候;
- 当你想通过RMI传输对象的时候;
3.怎么实现序列化
实现Serializable接口即可。4.代码
User对象
import java.io.Serializable;
public class User implements Serializable {
// public static final Long serialVersionUID = 1L;
private String name;
private String gender;
private int age;
private String hobby;
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
", hobby='" + hobby + '\'' +
'}';
}
public User() {
}
public User(String name, String gender, int age, String hobby) {
this.name = name;
this.gender = gender;
this.age = age;
this.hobby = hobby;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
}
SerializableTest测试
import java.io.*;
import java.util.ArrayList;
import java.util.List;
public class SerialzableTest {
public static void main(String[] args) {
Serial();
FanSerial();
}
/**
* 序列化对象
*/
public static void Serial(){
List<User> list =new ArrayList<>();
User user1 = new User("周星驰","男",18,"拍电影");
User user2 = new User("张学友","男",23,"爱唱歌");
User user3 = new User("张柏芝","女",25,"爱演戏");
list.add(user1);
list.add(user2);
list.add(user3);
ObjectOutputStream oos = null;
try {
oos = new ObjectOutputStream(new FileOutputStream("E:user.text"));
oos.writeObject(list);
oos.flush();
System.out.println("序列化成功");
} catch (IOException e) {
e.printStackTrace();
}finally {
if (oos!=null){
try {
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* 反序列化对象
*/
public static void FanSerial(){
ObjectInputStream ois = null;
List<User> list = new ArrayList<>();
try {
ois = new ObjectInputStream(new FileInputStream("E:user.text"));
list = (List<User>) ois.readObject();
System.out.println("反序列化成功");
for (User user : list) {
System.out.println(user.toString());
}
} catch (IOException e) {
e.printStackTrace();
}catch (ClassNotFoundException e){
e.printStackTrace();
}finally {
if(ois!=null){
try {
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
说明:在User对象中有一个变量SerialVersionUID被我注释了,在序列化的时候不写也不会报错,程序也能够正常执行,但是在读取的时候回报这个错误:local class incompatible: stream classdesc serialVersionUID = -5485257643592436780, local class serialVersionUID = 7924363931214305154。根据错误提示很容易找到错误所在,serialVersinoUID的值不一,所以读取发生错误,把注释删掉就不会报错。
注意:当你写入文件的时候,是一个一个的对象,那么读取的时候也必须是一个一个的对象进行接收;如果写入的是多个对象,最好用list集合装起来,writeObject(list)即可,读取的时候用list接收,打印只需遍历list即可;
特别要注意的地方:我之所以再次强调,是因为我遇到这个之后怎么也想不通,花了好半天才自行解决。写入的时候是writeObject(user),把一个一个的User直接写入,却用list来接收,编译不会出错,但是运行会报错。有的人可能会想了,我用集合来装对象,最后用集合接收合情合理,我也是这么想的,反正就是错的。所以说写入的如果是对象就用对象接收,写入的是集合就用集合接收,否则就会跟我一样报错。