java中的Serializable、transient关键字详解
1、Serializable 序列化接口
如下,写一个类实现Serializable,并标注序列化版本号
public class Foo implements Serializable {
private static final long serialVersionUID = -5809782578272943999L;
private int id;
private String name;
.
.
.
}实现序列化接口Serializable有什么用?
1.1、有什么用?
没有实现序列化的对象都保存在堆(Heap)中。 实现序列化后可以保存到一个文件里。
如下例:
// class Foo implements Serializable
Foo foo = new Foo();
foo.setId(1);
foo.setName("ho");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("foo.ser"));
oos.writeObject(student);
oos.flush();
oos.close();foo实例化后被保存在foo.ser文件中
foo.ser
Foo [id=1, name=ho]
1.2、什么情况下用?
1、该对象数据需要写入数据库
2、该对象需要通过网络、RMI、缓存等传递或保存
3、该对象需要在jvm与jvm间交流
1.3、要注意些什么
1、序列化只会保存属性值,不会保存方法
2、通过反序列化可以把序列化后的内容恢复成对象
3、声明为 static 和 transient 的成员变量,不能被序列化,static 成员变量是描述类级别的属性,transient 表示临时数据。
4、某个类可以被序列化,则其子类也可以被序列化
5、反序列化读取序列化对象的顺序要保持一致
2、transient 关键字
如下是LinkedList的部分源码
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
transient int size = 0;
transient Node<E> first;
.
.
.
}我们能看到size、first两个属性前面加了transient关键字。 transient 关键字,主要用来忽略我们不希望进行序列化的变量。
2.1、什么情况下用?
首先,当一个类需要序列化,但是某个属性不需要被序列化就可以加此关键字。 都有哪些场景呢?
1、一些敏感信息,如密码、银行卡号等
2、非必要信息,如LinkedList中的大小、位置等
2.2、要注意些什么
1、需要实现Serializable接口。
2、transient关键字只能修饰变量,而不能修饰方法和类。
3、本地变量是不能被transient关键字修饰的
4、实现Externalizable接口,需要在writeExternal方法中进行手工指定所要序列化的变量,这与是否被transient修饰无关。
3、序列化与反序列化
ObjectOutputStream:IO 类,包含序列化对象的方法,writeObject()
ObjectInputStream:IO 类,包含反序列化对象的方法,readObject()
序列化示例:
public static void main(String[] args) throws Exception {
// 创建 Java 对象(Foo必须已经实现了Serializable接口)
Foo foo = new Foo(22,"tt");
// 对象输出流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("foo"));
// 使用 writeObject 序列化对象
oos.writeObject(student);
// 刷新
oos.flush();
// 关闭流
oos.close();
}反序列化示例:
public static void main(String[] args) throws Exception {
// 对象输入流
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("foo"));
// 使用 readObject() 反序列化
Object obj = ois.readObject();
// 使用对象
System.out.println(obj);
// 关闭流
ois.close();
}反序列化需要借助文件输入流读取指定路径的二进制文件。
3.1、serialVersionUID 版本号的作用
JVM 首先会通过类名来区分 Java 类,类名不同,则不是同一个类。当类名相同时,JVM 就会通过序列化版本号来区分 Java 类,如果序列化版本号相同就为同一个类,序列化版本号不同就为不同的类。
到此这篇关于java中的Serializable、transient关键字详解的文章就介绍到这了,更多相关java的Serializable、transient内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
关于springboot配置druid数据源不生效问题(踩坑记)
今天日常跟着网课学习,学到了整合druid数据源,遇到了好几个坑,希望这篇文章可以帮助一些和我一样踩坑的人2021-09-09
Spring Boot使用GridFS实现文件的上传和下载方式
这篇文章主要介绍了Spring Boot使用GridFS实现文件的上传和下载方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-10-10
Jenkins打包Maven项目找不到mvn:not found的解决方案
文章讲述了在使用Docker重新部署Jenkins并使用流水线脚本打包项目时遇到的编译找不到mvn命令的问题,通过检查Jenkins服务器上的Maven安装、Maven插件、全局工具配置以及系统环境变量,最终解决了问题2025-11-11
详解Java中三种状态机实现方式来优雅消灭 if-else 嵌套
这篇文章主要为大家详细介绍了Java中三种状态机实现方式从而优雅消灭 if-else 嵌套,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下2025-08-08


最新评论