java.io.NotSerializableException: com.jshb.fengyun.wms.ui.secsystem.model.User$PlatsBean

本文介绍了使用ACache保存序列化对象时遇到的问题及解决办法。由于模型类中包含未被序列化的内部类而导致缓存失败,通过为该内部类添加序列化属性成功解决了这一问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

早上用ACache保存序列化对象时,报错了,查了半天,是因为模型类中含有内部类,这个内部类没有序列化导致的缓存失败,所以把这个内部类加上序列化即可解决问题

### Java 中关于 Redisson 的 NotSerializableException 解决方案 `java.io.NotSerializableException` 是一种常见的序列化异常,通常发生在尝试将未实现 `Serializable` 接口的对象进行序列化时。对于 Redisson 中的 `RedissonPermitExpirableSemaphore` 类型对象引发此异常的情况,以下是可能的原因及其解决方案。 #### 原因分析 1. **Redisson 对象本身不可序列化** 如果你在分布式环境中使用 Redisson 提供的功能(如信号量),而这些功能依赖于某些内部状态或上下文数据,则可能会因为这些数据未被标记为可序列化而导致异常[^3]。 2. **嵌套对象未实现 Serializable** 即使 `RedissonPermitExpirableSemaphore` 实现了 `Serializable`,但如果其成员变量中有未实现该接口的对象实例,也会触发 `NotSerializableException` 异常[^5]。 3. **闭包捕获外部变量** 在 Spark 或其他分布式计算框架中,如果通过 lambda 表达式或其他方式传递了一个包含复杂对象图的函数到远程节点执行,那么整个对象树都需要满足序列化条件。任何部分缺失都会导致失败[^4]。 #### 解决方案 为了处理上述问题,可以采取以下措施: 1. **确认目标类是否完全支持序列化** 验证所有涉及的对象都显式声明实现了 `java.io.Serializable` 接口,并且没有任何字段违反这一原则。例如: ```java public class MyCustomClass implements Serializable { private static final long serialVersionUID = 1L; // Ensure all fields are either transient or serializable themselves. private String name; private int age; // Getters and setters omitted for brevity. @Override public String toString() { return "MyCustomClass{" + "name='" + name + '\'' + ", age=" + age + '}'; } } ``` 2. **利用 Transient 关键字忽略特定属性** 若存在无法修改源码或者确实不需要保存的状态信息,可以通过将其定义成 `transient` 来跳过它们的序列化进程[^1]: ```java public class MyClassWithTransientField implements Serializable { private static final long serialVersionUID = 1L; private String importantData; private transient Object nonSerializableObject; // Constructors, getters/setters etc... } ``` 3. **自定义 writeObject 和 readObject 方法** 当默认机制不足以解决问题时,还可以重载这两个特殊方法来自定义行为[^2]: ```java private void writeObject(java.io.ObjectOutputStream out) throws IOException { out.defaultWriteObject(); // Custom serialization logic here if necessary. } private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); // Re-initialize any transient field after deserialization. } ``` 4. **替换为更轻便的数据结构 (推荐用于分布式场景)** 考虑到性能因素以及兼容性需求,在实际开发过程中建议尽可能采用简单的 POJOs 并配合 JSON 序列器比如 Jackson/Gson 进行转换而不是直接操作二进制流。 5. **针对 Redisson 特定情况调整配置** - 使用 RLock/RCountDownLatch 等替代品代替原生锁; - 将业务逻辑拆分至无状态的服务端组件调用而非随任务广播给各个工作节点; --- ### 示例代码片段 假设我们正在调试一个基于 Redisson 的限流模块遇到此类错误,下面是修正后的版本之一: ```java import org.redisson.api.RSemaphoreAsync; import org.redisson.api.RedissonClient; import java.io.Serializable; public class RateLimitedService implements Serializable { private static final long serialVersionUID = 1L; private transient RSemaphoreAsync semaphore; public RateLimitedService(RedissonClient redisson){ this.semaphore = redisson.get SemaphoreAsync("rate_limit_key"); } public boolean tryAcquire(){ return CompletableFuture.supplyAsync(() -> semaphore.tryAcquire()).join(); } } ``` 在此例子中我们将原始类型的引用设为了瞬态 (`transient`) ,从而避免不必要的序列化开销同时也规避掉了潜在的风险点。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值