Java序列化与反序列化

不算难理解

序列化和反序列化这两个名词很早就从 Java 的反序列化漏洞里听过了
但当时由于实力不足,不知道是什么意思,也就很懵逼的过去了
今天学了序列化和反序列化,理解起来不算难吧

ObjectOutputStream 序列化

把 Java 中实例化的对象转换为字节数据,这样就能把它存储起来,这样以后要用的时候就不用在 new 一个对象了
也可以把这个序列化后的数据通过网络发送到其他电脑上,这样别的电脑就可以使用这个类了

使用方法:

1
2
3
4
5
6
FileOutputStream fos = new FileOutputStream("person.txt"); //创建一个输出流对象
ObjectOutputStream oos = new ObjectOutputStream(fos); //创建一个序列化对象,并传入输出流对象,实例化后的文件就存在输出流指定的文件中
Person ren = new Person("mua", 10); //实例化一个 Person 对象
oos.writeObject(ren); //序列化对象
fos.close();
oos.close();

然后就会发现多了一个 person.txt 的文件,但由于编码问题,看到的是乱码

ObjectInputStream 反序列化

对象实例化后产生的文件可以通过反序列化变回一个对象
变回的对象都是 Object 类的对象,需要转换一下

1
2
3
4
5
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.txt")); //创建读取对象
Object o = ois.readObject(); //读取对象
ois.close();
Person ren = (Person) o; //类型转换
System.out.println(ren);

存储和读取多个对象

可以用 ArrayList 来创建一个对象的数组,然后存储起来,反序列化的时候用 ArrayList 接收

1
2
3
4
5
6
7
ArrayList<Person> arr = new ArrayList<>(); //创建一个 Person 类对象数组
arr.add(new Person("Wife", 16)); //添加元素
arr.add(new Person("Sister", 14));

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.txt")); //创建序列化对象
oos.writeObject(arr); //序列化整个数组
oos.close(); //释放资源

反序列化多个对象

1
2
3
4
5
6
7
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.txt")); //创建读取对象
Object o = ois.readObject(); //读取数组,返回的是 Object 类
ArrayList<Person> per = (ArrayList<Person>) o; //类型转换
for (Person person : per) {
System.out.println(person); //输出对象
}
ois.close(); //释放资源

序列化类的定义

如果一个类所创建的对象要实现序列化,就要继承 Serializable 接口,这个接口里面什么方法都没有,之所以继承只是为了标记这个类是可序列化的

1
2
3
public class Person implements Serializable{
static final long serialVersionUID = 100; //序列号id,这样就可以固定这个类序列化后的id
}

一个类如果可以被序列化,那么就可以根据这个类的定义算出它的序列id,类似于进行了一次hash运算
如果对类进行了修改,这个id就会不一样,反序列化的时候需要用到这个id,如果id不一样就会反序列化失败
此时如果在定义类的时候固定这个id,就不会有这种困难了
serialVersionUID 必须加上static final 这两个修饰符

transient和static修饰符很像,它们定义的参数都不能参加序列化
transient只是不参加序列化,它没有static的可以不实例化类就调用的特性


马上就可以开始学习网络编程了,虽然之前学过 Python 的网络编程,但两个语言的差别还是挺大的,还是要好好学
马上要放暑假了,回家可以边学 Java,边学学 Linux 开发 (⸝⸝•‧̫•⸝⸝)