# **1. 序列化与反序列化**
## **1.1 序列化**
1. Java序列化能够将实例对象写入字节流中(**只序列化对象属性值,而不序列化方法**)
2. 序列化后的对象(字节信息)可用于网络传输、持久化到数据库、磁盘中
## **1.2 反序列化**
需要对象的时候,再从序列化出来的字节信息中构造出原来的对象
# **2. 实现序列化**
`Java`中要使一个类可以序列化,实现`java.io.Serializable` 接口
1. user对象
~~~
@Data
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
private String age;
}
~~~
2. 测试
~~~
public class serializeTest {
public static void main(String[] args) throws Exception {
User user = new User();
user.setName("fufu");
user.setAge("18");
serialize(user);
System.out.println("Java序列化前的结果:{} " + user.toString());
User duser = deserialize();
System.out.println("Java反序列化的结果:{} " + duser.toString());
}
private static void serialize(User user) throws Exception {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("C:\\Users\\93130\\Desktop\\user.txt")));
oos.writeObject(user);
oos.close();
}
private static User deserialize() throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("C:\\Users\\93130\\Desktop\\user.txt")));
return (User) ois.readObject();
}
}
~~~
输出
```
Java序列化前的结果:{} User(name=fufu, age=18)
Java反序列化的结果:{} User(name=fufu, age=18)
```
产生文件
![](https://img.kancloud.cn/c7/4f/c74f3d139ed479c555232bd70bd05be9_713x257.png)
# 3. **`serialVersionUID`** 属性
1. 因为序列化对象时,如果不显示的设置`serialVersionUID`,Java在序列化时会根据对象属性自动的生成一个`serialVersionUID`,再进行存储或用作网络传输。
2. 在反序列化时,会根据对象属性自动再生成一个新的`serialVersionUID`,和序列化时生成的`serialVersionUID`进行比对,两个`serialVersionUID`相同则反序列化成功,否则就会抛异常。
3. 而当显示的设置`serialVersionUID`后,Java在序列化和反序列化对象时,生成的`serialVersionUID`都为我们设定的`serialVersionUID`,这样就保证了反序列化的成功。
例如将对象user序列化后,对user对象源码进行了修改,此时再去反序列化会报错,因为serialVersionUID不一样了;如果显示指定则可以避免处理类情况
# 4. **transient**
序列化对象时如果希望哪个属性不被序列化,则用`transient`关键字修饰即可
~~~
@Data
public class User implements Serializable {
private transient String name;
private String age;
}
~~~
可以看到字段`name`的值没有被保存到磁盘中,一旦变量被`transient`修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
复制
~~~
Java序列化前的结果: User(name=fufu, age=18)
Java反序列化的结果:User(name=null, age=18)
~~~
一个静态变量不管是否被`transient`修饰,均不能被序列化。 因为`static`修饰的属性是属于类,而非对象。
- 计算机网络
- 基础_01
- tcp/ip
- http转https
- Let's Encrypt免费ssl证书(基于haproxy负载)
- what's the http?
- 网关
- 网络IO
- http
- 工具
- Git
- 初始本地仓库并上传
- git保存密码
- Gitflow
- maven
- 1.生命周期命令
- 聚合与继承
- 插件管理
- assembly
- 资源管理插件
- 依赖范围
- 分环境打包
- dependencyManagement
- 版本分类
- 找不到主类
- 无法加载主类
- 私服
- svn
- gradle
- 手动引入第三方jar包
- 打包exe文件
- Windows
- java
- 设计模式
- 七大原则
- 1.开闭原则
- 2. 里式替换原则
- 3. 依赖倒置原则
- 4. 单一职责原则
- 单例模式
- 工厂模式
- 简单工厂
- 工厂方法模式
- 抽象工厂模式
- 观察者模式
- 适配器模式
- 建造者模式
- 代理模式
- 适配器模式
- 命令模式
- json
- jackson
- poi
- excel
- easy-poi
- 规则
- 模板
- 合并单元格
- word
- 读取
- java基础
- 类路径与jar
- 访问控制权限
- 类加载
- 注解
- 异常处理
- String不可变
- 跨域
- transient关键字
- 二进制编码
- 泛型1
- 与或非
- final详解
- Java -jar
- 正则
- 读取jar
- map
- map计算
- hashcode计算原理
- 枚举
- 序列化
- URLClassLoader
- 环境变量和系统变量
- java高级
- java8
- 1.Lambda表达式和函数式接口
- 2.接口的默认方法和静态方法
- 3.方法引用
- 4.重复注解
- 5.类型推断
- 6.拓宽注解的应用场景
- java7-自动关闭资源机制
- 泛型
- stream
- 时区的正确理解
- StringJoiner字符串拼接
- 注解
- @RequestParam和@RequestBody的区别
- 多线程
- 概念
- 线程实现方法
- 守护线程
- 线程阻塞
- 笔试题
- 类加载
- FutureTask和Future
- 线程池
- 同步与异步
- 高效简洁的代码
- IO
- ThreadLocal
- IO
- NIO
- 图片操作
- KeyTool生成证书
- 压缩图片
- restful
- 分布式session
- app保持session
- ClassLoader.getResources 能搜索到的资源路径
- java开发规范
- jvm
- 高并发
- netty
- 多线程与多路复用
- 异步与事件驱动
- 五种IO模型
- copy on write
- code style
- 布隆过滤器
- 笔试
- 数据库
- mybatis
- mybatis与springboot整合配置
- pagehelper
- 分页数据重复问题
- Java与数据库之间映射
- 拦截器
- 拦截器应用
- jvm
- 堆内存测试
- 线程栈
- 直接内存
- 内存结构
- 内存模型
- 垃圾回收
- 调优
- 符号引用
- 运行参数
- 方法区
- 分带回收理论
- 快捷开发
- idea插件
- 注释模板
- git
- pull冲突
- push冲突
- Excel处理
- 图片处理
- 合并单元格
- easypoi
- 模板处理
- 响应式编程
- reactor
- reactor基础
- jingyan
- 规范
- 数据库