Java序列化

本文详细介绍了Java对象序列化的基本概念及其应用场景,包括序列化与反序列化的过程、实现序列化的两种接口(Serializable与Externalizable),以及序列化过程中的注意事项如serialVersionUID的作用、静态变量与transient关键字的应用等。

对象序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。

  • 序列化:将java对象转换为二进制字节码的过程。
  • 反序列化:将二进制字节码转换为java对象的过程。
  • 让某个java对象具有序列化机制,需要实现以下两个接口之一
    • Serializable
    • Externalizable
  • private static final long serialVersionUID:这个变量用来表示类的不同版本之间的兼容性。推荐显式声明。不声明的情况下,它的值是Java运行时环境根据类的内部细节自动生成的。若类的源代码作了修改,serialVersionUID 可能发生变化。
    • serialVersionUID不同,则不能反序列化成功。
  • 类中的静态变量不能被序列化,因为序列化的是对象的状态,而静态变量是类的状态。
  • Transient:该关键字用来阻止字段被序列化。
  • 类中的引用类型的变量也需要被实现Serializable接口,否则不会被序列化。
  • 父类也需要实现Serializable接口,否则不会被序列化。反序列化时会默认调用父类的无参构造器。
  • 可以将不需要序列化的属性变量抽取到一个父类中,父类不实现Serializable接口即可,简化赘余Transient的使用。
  • 在序列化过程中,虚拟机会试图调用对象类里的writeObjectreadObject 方法,进行用户自定义的序列化和反序列化,如果没有这样的方法,则默认调用是 ObjectOutputStream 的 defaultWriteObject 方法以及 ObjectInputStream 的 defaultReadObject 方法 。请参考
分布式微服务企业级系统是一个基于Spring、SpringMVC、MyBatis和Dubbo等技术的分布式敏捷开发系统架构。该系统采用微服务架构和模块化设计,提供整套公共微服务模块,包括集中权限管理(支持单点登录)、内容管理、支付中心、用户管理(支持第三方登录)、微信平台、存储系统、配置中心、日志分析、任务和通知等功能。系统支持服务治理、监控和追踪,确保高可用性和可扩展性,适用于中小型企业的J2EE企业级开发解决方案。 该系统使用Java作为主要编程语言,结合Spring框架实现依赖注入和事务管理,SpringMVC处理Web请求,MyBatis进行数据持久化操作,Dubbo实现分布式服务调用。架构模式包括微服务架构、分布式系统架构和模块化架构,设计模式应用了单例模式、工厂模式和观察者模式,以提高代码复用性和系统稳定性。 应用场景广泛,可用于企业信息化管理、电子商务平台、社交应用开发等领域,帮助开发者快速构建高效、安全的分布式系统。本资源包含完整的源码和详细论文,适合计算机科学或软件工程专业的毕业设计参考,提供实践案例和技术文档,助力学生和开发者深入理解微服务架构和分布式系统实现。 【版权说明】源码来源于网络,遵循原项目开源协议。付费内容为本人原创论文,包含技术分析和实现思路。仅供学习交流使用。
### 序列化的含义 序列化指将堆内存中的 Java 对象数据,通过某种方式存储到磁盘文件中,或者传递给其他网络节点(网络传输),即将对象转化为二进制,用于保存或网络传输。反序列化则是从 IO 流中恢复对象[^1][^4]。 ### 序列化的意义 序列化机制允许将实现序列化Java 对象转换为字节序列,这些字节序列可以保存在磁盘上,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使得对象可以脱离程序的运行而独立存在[^1]。 ### 序列化的使用场景 所有可在网络上传输的对象都必须是可序列化的,比如 RMI(remote method invoke,即远程方法调用),传入的参数或返回的对象都是可序列化的,否则会出错;所有需要保存到磁盘的 Java 对象都必须是可序列化的。通常建议程序创建的每个 JavaBean 类都实现 Serializable 接口[^1]。 ### 序列化实现的方式 #### Serializable 接口 - **普通序列化**:实现 Serializable 接口后,可使用 ObjectOutputStream 将对象写入流,使用 ObjectInputStream 从流中读取对象。 ```java import java.io.*; class Person implements Serializable { String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } } public class SerializationExample { public static void main(String[] args) { Person person = new Person("John", 30); try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser"))) { oos.writeObject(person); } catch (IOException e) { e.printStackTrace(); } try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser"))) { Person deserializedPerson = (Person) ois.readObject(); System.out.println(deserializedPerson.name + " " + deserializedPerson.age); } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } } ``` - **成员是引用的序列化**:若类的成员是引用类型,该引用类型也必须是可序列化的,否则当前类无法实现序列化。 - **同一对象序列化多次的机制**:Java 序列化算法会保证同一对象多次序列化时,不会重复序列化对象的内容,而是只记录对象的引用。 - **Java 序列化算法潜在的问题**:例如序列化版本号不匹配、性能问题等。 - **可选的自定义序列化**:可通过实现 `writeObject` 和 `readObject` 方法来自定义序列化和反序列化过程。 #### Externalizable 接口 Externalizable 接口强制自定义序列化,需要实现 `writeExternal` 和 `readExternal` 方法。 ```java import java.io.*; class Employee implements Externalizable { String name; int id; public Employee() {} public Employee(String name, int id) { this.name = name; this.id = id; } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(name); out.writeInt(id); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { name = (String) in.readObject(); id = in.readInt(); } } ``` ### 序列化版本号 serialVersionUID serialVersionUID 用于确保序列化和反序列化时类的版本一致性。若没有显式定义 serialVersionUID,Java 会根据类的结构自动生成一个。当类的结构发生变化时,可能会导致 serialVersionUID 改变,从而在反序列化时抛出 `InvalidClassException`。建议显式定义 serialVersionUID。 ```java import java.io.Serializable; class MyClass implements Serializable { private static final long serialVersionUID = 1L; // 类的成员和方法 } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值