简单学习序列化

    Java序列化是将一个对象编码成一个字节流,反序列化将字节流编码转换成一个对象。 序列化是Java中实现持久化存储的一种方法;为数据传输提供了线路级对象表示法。

    Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体(类)的serialVersionUID进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。 

    Eclipse中The serializable class XXXXXX  does not declare a static final serialVersionUID field of type long出现这样的警告处理办法。 
    当采用程序的Add default Serial version ID修复时,Eclipse会加上:private static final long serialVersionUID = 1L; 
    当采用程序的Add generated Serial version ID修复时,Eclipse会加上:private static final long serialVersionUID = xxxxL; 

    其实这个问题出现的具体原因是和序列化中的这个serialVersionUID有关。 serialVersionUID 用来表明类的不同版本间的兼容性。有两种生成方式: 一个是默认的1L;另一种是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段 。在JDK中,可以利用JDK的bin目录下的serialver.exe工具产生这个serialVersionUID 的值,对于Test.class,执行命令: serialver Test   这时JVM(java虚拟机)会生成一个哈希字段。 
    对比一下这个哈希字段的值与方法2中生成的字段值是一样的,可见,在CMD中使用serialver指令就是根据类名、接口名、成员方法及属性等来生成哈希字段的。 

java类中为什么需要重载 serialVersionUID 属性。 

    当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。 把Java对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为Java对象的过程称为对象的反序列化。 

对象的序列化主要有两种用途: 

  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中。
  2) 在网络上传送对象的字节序列。 

java.io.ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。     java.io.ObjectInputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。 只有实现了Serializable或Externalizable接口的类的对象才能被序列化。Externalizable接口继承自Serializable接口,实现Externalizable接口的类完全由自身来控制序列化的行为,而仅实现Serializable接口的类可以采用默认的序列化方式 。 凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量:private static final long serialVersionUID; 类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的serialVersionUID。

显式地定义serialVersionUID有两种用途: 

        1)在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。 

  2)当你序列化了一个类实例后,希望更改一个字段或添加一个字段,不设置serialVersionUID,所做的任何更改都将导致无法反序化旧有实例,并在反序列化时抛出一个异常。如果你添加了serialVersionUID,在反序列旧有实例时,新添加或更改的字段值将设为初始化值(对象为null,基本类型为相应的初始默认值),字段被删除将不设置。

序列化算法一般会按步骤:

将对象实例相关的类元数据输出。
递归地输出类的超类描述直到不再有超类。
类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。
从上至下递归输出实例的数据。

基于数据驱动的 Koopman 算子的递归神经网络模型线性化,用于纳米定位系统的预测控制研究(Matlab代码实现)内容概要:本文围绕“基于数据驱动的Koopman算子的递归神经网络模型线性化”展开,旨在研究纳米定位系统的预测控制方法。通过结合数据驱动技术与Koopman算子理论,将非线性系统动态近似为高维线性系统,进而利用递归神经网络(RNN)建模并实现系统行为的精确预测。文中详细阐述了模型构建流程、线性化策略及在预测控制中的集成应用,并提供了完整的Matlab代码实现,便于科研人员复现实验、优化算法并拓展至其他精密控制系统。该方法有效提升了纳米级定位系统的控制精度与动态响应性能。; 适合人群:具备自动控制、机器学习或信号处理背景,熟悉Matlab编程,从事精密仪器控制、智能制造或先进控制算法研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①实现非线性动态系统的数据驱动线性化建模;②提升纳米定位平台的轨迹跟踪与预测控制性能;③为高精度控制系统提供可复现的Koopman-RNN融合解决方案; 阅读建议:建议结合Matlab代码逐段理解算法实现细节,重点关注Koopman观测矩阵构造、RNN训练流程与模型预测控制器(MPC)的集成方式,鼓励在实际硬件平台上验证并调整参数以适应具体应用场景。
### 序列化与反序列化的概念 序列化是指将对象的状态转换为可以存储或传输的形式的过程。这种形式通常是字节流或者字符串,比如JSON、XML或者其他格式的数据表示方式[^2]。通过这种方式,程序可以在不同的环境中保存数据或将数据发送到远程位置。 反序列化则是指将这些被序列化的数据重新解析并恢复成原始的对象结构的过程[^1]。这使得可以从持久状态中读取对象,并将其还原回内存中的活动实例。 --- ### Python 中 JSON 的序列化与反序列化实现 #### 基本操作 在 Python 中,`json` 是用于处理 JSON 数据的标准库模块。它提供了 `dumps()` 和 `loads()` 方法来完成序列化和反序列化的工作: - **序列化 (对象 -> 字符串)** 使用 `json.dumps(obj)` 将 Python 对象转化为 JSON 格式的字符串。 - **反序列化 (字符串 -> 对象)** 使用 `json.loads(json_str)` 将 JSON 格式的字符串转化回 Python 对象。 以下是简单的示例代码: ```python import json # 定义一个字典作为待序列化的对象 data = { 'name': 'Alice', 'age': 30, 'is_student': False } # 序列化过程 serialized_data = json.dumps(data, indent=4) print("Serialized Data:", serialized_data) # 反序列化过程 deserialized_data = json.loads(serialized_data) print("Deserialized Data:", deserialized_data) ``` 上述代码展示了如何利用标准函数进行基本的序列化和反序列化工作。 --- #### 自定义解码器 如果需要更复杂的逻辑,可以通过继承 `json.JSONDecoder` 并覆盖其方法来自定义行为。例如,在某些情况下可能希望修改默认的行为以适应特定需求。下面是一个例子展示如何创建自定义类来进行高级别的控制: ```python import json class CustomDecoder(json.JSONDecoder): def decode(self, s, _w=json.whitespace.match): result = super().decode(s, _w=_w) # 调用父类的方法执行基础功能 if isinstance(result, dict): # 如果结果是字典,则进一步加工 processed_result = {k.upper(): v for k, v in result.items()} return processed_result return result # 测试自定义解码器 custom_json_string = '{"name": "Bob", "age": 25}' decoded_object = json.loads(custom_json_string, cls=CustomDecoder) print(decoded_object) # 输出 {'NAME': 'Bob', 'AGE': 25} ``` 此部分说明了当面对复杂场景时扩展框架的能力。 --- ### C# 实现 Json 序列化与反序列化 对于另一种流行的语言——C# 来说,同样支持方便快捷的方式来做同样的事情。借助于 .NET 提供的强大工具集,开发者能够轻松编写相应代码片段如下所示: ```csharp using System; using Newtonsoft.Json; public class Person { public string Name { get; set; } public int Age { get; set; } } public static class JsonSerializationExample { public static string SerializeObjectToJson(Person person) { return JsonConvert.SerializeObject(person); } public static Person DeserializeJsonToObject(string jsonString) { return JsonConvert.DeserializeObject<Person>(jsonString); } public static void Main() { var originalPerson = new Person {Name="John Doe", Age=28}; // Serialization process. string serializedData = SerializeObjectToJson(originalPerson); Console.WriteLine($"Serialized data: {serializedData}"); // Deserialization process. Person restoredPerson = DeserializeJsonToObject(serializedData); Console.WriteLine($"Restored name: {restoredPerson.Name}, age: {restoredPerson.Age}"); } } ``` 这里采用了第三方 NuGet 包 `Newtonsoft.Json` 来简化开发流程[^3]。 --- ### 总结 无论是哪种编程语言都提供了一套成熟的机制帮助程序员高效地解决实际问题。理解它们背后原理的同时掌握具体实践技巧是非常重要的技能之一。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值