java反序列化学习笔记

序列化

java的ObjectOutputStream类的writeObject()方法用于将对象序列化。一个对象想要序列化,必须满足:

  • 实现java.io.Serializable接口
  • 该类的所有属性必须是可序列化的,若某属性不需要序列化,需要使用transient关键字修饰(static修饰的属性也不会进行序列化)

Demo1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Test implements java.io.Serializable{
public String name;
public int age;

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

public static void main(String[] args) throws IOException {
//创建FileOutputStream对象,将其封装到ObjectOutputStream对象中
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("/Users/gtfly/Desktop/1.txt"));
//完成对象的序列化,并将其发送给FileOutputStream
out.writeObject(new Test("gtfly", 20));
//关闭资源
out.close();
}
}

运行后,会创建一个1.txt文件,里面存储着序列化后的数据,使用16进制编辑器打开:

使用SerializationDumper来查看:

除此之外,可以在序列化的类中添加指定方法来实现更精确的序列化控制

Demo2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class Test implements java.io.Serializable{
public String name;
public int age;

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

private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
//在使用正常的序列化之后,加上自己需要的信息,一起序列化。
oos.writeObject("this is a test");
}

public static void main(String[] args) throws IOException {
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("/Users/gtfly/Desktop/2.txt"));
out.writeObject(new Test("gtfly", 20));
out.writeObject("this is a test");
out.close();
}
}

使用SerializationDumper来查看序列化后的数据:

写入的字符串this is a test被放在objectAnnotation的位置

反序列化

java的ObjectInputStreamreadObject方法用于实现反序列化

反序列化Demo1中生成的序列化字符串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.io.*;

public class Test implements java.io.Serializable{
public String name;
public int age;

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

public static void main(String[] args) throws IOException,ClassNotFoundException {
ObjectInputStream out = new ObjectInputStream(new FileInputStream("/Users/gtfly/Desktop/1.txt"));
Test a = (Test) out.readObject();
System.out.println(a.name);
out.close();
}
}
//gtfly

反序列化Demo2中生成的序列化字符串:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import java.io.*;

public class Test implements java.io.Serializable{
public String name;
public int age;

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

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
//在反序列化后,读取自己添加的信息。一起反序列化
Object o = ois.readObject();
System.out.println(o);
}

public static void main(String[] args) throws IOException,ClassNotFoundException {
ObjectInputStream out = new ObjectInputStream(new FileInputStream("/Users/gtfly/Desktop/2.txt"));
out.readObject();
//关闭资源
out.close();
}
}
//this is a test