本文 Github开源项目:github.com/hansonwang99/JavaCollection 中已收录,有详细自学编程学习路线、面试题和面经、编程资料及系列技术文章等,资源持续更新中。.. 工人 曾几何时,对于Jav…

一、工具人
曾几何时,对于Java的序列化的认知一直停留在:「实现个 Serializbale 接口」不就好了的状态,直到 …
所以这次抽时间再次重新捧起了尘封已久的《Java编程思想》,就像之前梳理《枚举部分知识》一样,把「序列化和反序列化」这块的知识点又重新审视了一遍。
### 二、序列化是干啥用的
序列化的原本意图是希望对一个Java对象作一下“变换”,变成字节序列,这样一来方便持久化存储到磁盘,避免程序运行结束后对象就从内存里消失,另外变换成字节序列也更便于网络运输和传播,所以概念上很好理解:
序列化:把Java对象转换为字节序列。
反序列化:把字节序列恢复为原先的Java对象。
而且序列化机制从某种意义上来说也弥补了平台化的一些差异,毕竟转换后的字节流可以在其他平台上进行反序列化来恢复对象。
事情就是那么个事情,看起来很简单,不过后面的东西还不少,请往下看。
### 三、对象如何序列化
然而Java目前并没有一个关键字可以直接去定义一个所谓的“可持久化”对象。
象的持久化和反持久化需要靠程序员在代码里手动显式地进行序列化和反序列化还原的动作。
举个例子,假如我们要对 Student 类对象序列化到一个名为 student.txt 的文本文件中,然后再通过文本文件反序列化成 Student 类对象:
1、Student类定义
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class Student implements Serializable {
private String name;
private Integer age;
private Integer score;
public String toString() {
return "Student:" + 'n' +
"name = " + this.name + 'n' +
"age = " + this.age + 'n' +
"score = " + this.score + 'n'
;
}
// ... 其他省略 ...
}
`2、序列化```java
public static void serialize( ) throws IOException {
Student student = new Student();
student.setName("CodeSheep");
student.setAge( 18 );
student.setScore( 1000 );
ObjectOutputStream objectOutputStream =
new ObjectOutputStream( new FileOutputStream( new File("student.txt") ) );
objectOutputStream.writeObject( student );
objectOutputStream.close();
System.out.println("序列化成功!已经生成student.txt文件");
System.out.println("==============================================");
}
`3、反序列化```java
public static void deserialize( ) throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream =
new ObjectInputStream( new FileInputStream( new File("student.txt") ) );
Student student = (Student) objectInputStream.readObject();
objectInputStream.close();
System.out.println("反序列化结果为:");
System.out.println( student );
}
```
4、运行结果
控制台打印:
序列化成功!已经生成student.txt文件
1 | public class Student implements Serializable { |
1 | 反序列化结果为: |
name = CodeSheep
age = 18
score = 1000
1 |
|
1 | student.setScore( 100 ); |
}
接下来我们在```text Student类里面动点手脚,比如在里面再增加一个名为```text
studentID
1 | 这时候,我们拿刚才已经序列化到本地的 `student.txt` 文件,还用如下代码进行反序列化,试图还原出刚才那个 `Student` 对象: |
1 | // 调用默认的反序列化函数 |
1 | // 手工检查反序列化后学生成绩的有效性,若发现有问题,即终止操作! |
}
`比如我故意将学生的分数改为```text
101
1 | 对于上面的代码,有些小伙伴可能会好奇,为什么自定义的 `private` 的 `readObject()` 方法可以被自动调用,这就需要你跟一下底层源码来一探究竟了,我帮你跟到了 `ObjectStreamClass` 类的最底层,看到这里我相信你一定恍然大悟: |
}
1 | 这样一来,当反序列化从流中读取对象时, `readResolve()` ``` 会被调用,用其中返回的对象替代反序列化新建的对象。 |
本文标题: 序列化反序列化我
发布时间: 2025年01月27日 00:00
最后更新: 2025年12月30日 08:54
原始链接: https://haoxiang.eu.org/721628cf/
版权声明: 本文著作权归作者所有,均采用CC BY-NC-SA 4.0许可协议,转载请注明出处!

