kotlin使用com.alibaba.fastjson.JSONException: default constructor not found

在使用Kotlin与Fastjson 1.1.62版本配合时,可能出现`default constructor not found`错误。推荐使用1.1.61稳定版以解决问题。对于Kotlin的data类和普通类,可以添加空构造器。异常源于1.1.62版本新增的Kotlin判断,而在Kotlin 1.1.4中,由于反射创建构造器时找不到对应类导致异常。期望Fastjson官方能尽快修复此问题。

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

使用kotlin,在用fastjson来解析json数据时,出现这个错误
目前fastjson最新版本是1.1.62,不过还不稳定,出现这个问题建议使用1.1.61
github地址:https://github.com/ttarfall/fastjson
目前这个错误在使用kotlin的data数据类和普通数据类都会有,解决方法:

  • 使用1.1.61稳定版
  • 无使用 普通数据类 并且像这样多增加一个空构造器
class UserInfo{
   
   
    constructor()

    constructor(email: String, id: String, name: String)
}

期待官网能尽快更新这个问题
那下边我们来源码分析一下出现这个错误的原因:(这里主要比较的1.1.61和1.1.62)
由于官网是从1.1.61开始兼容kotlin解析,之前版本如果解析出错正常,因为没兼容,可能会有莫名其妙的错误,哈哈~~~
我们的异常是从这个方法抛出的:


                
<think>首先,用户的问题是关于FastJSON的CloneUtil.deepClone方法报错“default constructor not found”,具体针对java.util.Arrays$ArrayList。用户提到“我想用户希望了解在使用 FastJSON 进行深拷贝时,出现 'default constructor not found' 错误的原因,并寻求解决方案。”所以,我需要围绕这个主题展开。 关键点: - 错误:com.alibaba.fastjson.JSONException: default constructor not found. class java.util.Arrays$ArrayList - 场景:使用FastJSON的CloneUtil.deepClone方法进行深拷贝。 - 需求:解释原因并提供解决方案。 从系统级指令: - 所有行内数学表达式使用$...$格式,但这里可能不涉及数学表达式,因为主题是编程错误。 - 独立公式使用$$...$$格式并单独成段,同样可能不适用。 - LaTeX语法正确:确保任何数学表达正确。 - 使用中文回答:整个响应必须用中文。 - 生成相关问题:在回答末尾添加相关问题。 - 回答结构清晰,帮助用户逐步解决问题:组织内容为步骤或清晰的解释。 - 引用末尾添加引用标识:如[^1],基于提供的引用。提供的引用[1]到[5]是关于FastJSON的类似错误,但不是完全相同。我需要参考这些。 提供的引用: - [^1]: 关于RefundVo的错误。 - [^2]: Kotlin使用FastJSON的解决方案,建议使用1.1.61或添加空构造器。 - [^3]: 类似错误,针对DelayAddSkuMsg。 - [^4]: 添加@Builder注解导致的问题,解决方案是添加@NoArgsConstructor和@AllArgsConstructor。 - [^5]: 在测试类中,缺少无参构造方法,添加即可。 核心原因:FastJSON在反序列化时需要一个默认的无参构造函数(default constructor)来创建对象实例。如果类没有提供无参构造函数,就会抛出“default constructor not found”异常。 特定于java.util.Arrays$ArrayList: - java.util.Arrays$ArrayList是Arrays.asList()返回的内部类,它不是公开的,并且可能没有公共的无参构造函数。Arrays.asList()返回一个固定大小的列表,其实现是Arrays的内部类。 现在,构建回答: 1. **解释错误原因**:FastJSON在反序列化时需要调用类的无参构造函数来创建对象。如果类没有无参构造器(无论是显式还是默认),就会报错。 2. **针对java.util.Arrays$ArrayList**:这个类是Arrays.asList()创建的,它没有公共的无参构造器,因为它是内部类。FastJSON无法直接实例化它。 3. **解决方案**: - 避免直接使用Arrays.asList()进行深拷贝,因为它返回不可变列表。 - 使用其他方式创建列表,如new ArrayList<>(Arrays.asList(...))。 - 在自定义类中,确保有无参构造器。 - 对于FastJSON的深拷贝,考虑使用其他库或自定义方法。 4. **逐步解决问题**: - 步骤1: 理解错误根源。 - 步骤2: 修改代码以避免使用问题类。 - 步骤3: 添加无参构造器(如果自定义类)。 - 步骤4: 测试解决方案。 5. **引用参考**:在解释中引用提供的引用,例如[^2]、[^4]、[^5]提到添加无参构造器。 6. **生成相关问题**:在末尾添加相关问题。 结构化回答: - 开头:简要概述问题。 - 原因:详细解释为什么发生。 - 解决方案:具体步骤。 - 代码示例:提供代码片段。 - 相关问题:列出相关问题。 确保中文回答。</think>### FastJSON CloneUtil.deepClone 报错 "default constructor not found java.util.Arrays$ArrayList" 的解决方案 在使用 FastJSON 的 `CloneUtil.deepClone` 方法进行深拷贝时,遇到 "com.alibaba.fastjson.JSONException: default constructor not found. class java.util.Arrays$ArrayList" 错误,这通常是因为 FastJSON 在反序列化过程中需要调用类的默认无参构造函数(即无参数的构造方法)来创建对象实例。但 `java.util.Arrays$ArrayList` 是 Java 标准库中的一个内部类(由 `Arrays.asList()` 方法返回),它没有公共的无参构造器,导致 FastJSON 无法直接实例化它。下面我将逐步解释原因并提供解决方案,帮助您彻底解决此问题。 #### 错误原因详解 1. **FastJSON 反序列化机制**: FastJSON 在深拷贝或反序列化时,依赖反射机制创建对象实例。这要求目标类必须有一个可访问的无参构造函数(default constructor)。如果类没有显式定义无参构造器,Java 编译器会隐式生成一个默认的;但如果类定义了其他构造器(如全参构造器),则默认无参构造器不会被自动创建[^5]。 对于 `java.util.Arrays$ArrayList`: - 它是 `Arrays.asList()` 返回的内部类,设计为不可变(immutable),且未提供公共的无参构造器。 - 当您尝试深拷贝一个由 `Arrays.asList()` 创建的列表时,例如: ```java List<String> list = Arrays.asList("a", "b", "c"); Object cloned = CloneUtil.deepClone(list); // 报错点 ``` FastJSON 会尝试实例化 `Arrays$ArrayList`,但因其构造器私有,抛出 "default constructor not found" 异常。 2. **常见触发场景**: - 您可能在处理集合类(如 List)的深拷贝时,使用了 `Arrays.asList()` 创建列表。 - 类似错误也出现在自定义类中,如果类缺少无参构造器(参考引用[^4][^5]),但本例焦点是 Java 内部类。 #### 解决方案步骤 解决此问题的核心是避免直接深拷贝不可变的内部类实例,或改用可序列化的替代方案。以下是具体步骤,确保代码兼容 FastJSON: 1. **避免使用 `Arrays.asList()` 创建列表**: `Arrays.asList()` 返回的列表是固定大小的,不适合深拷贝。改用 `ArrayList` 或其他可变集合类。 - **修改代码示例**: 将 `Arrays.asList()` 替换为 `new ArrayList<>()`,确保列表可被正确实例化。 ```java // 错误示例:使用 Arrays.asList() 导致问题 // List<String> originalList = Arrays.asList("a", "b", "c"); // 正确修改:使用 ArrayList 创建可变列表 List<String> originalList = new ArrayList<>(Arrays.asList("a", "b", "c")); Object cloned = CloneUtil.deepClone(originalList); // 不再报错 ``` 这样,FastJSON 能识别 `ArrayList` 的公共无参构造器,完成深拷贝。 2. **为自定义类添加无参构造器(如果适用)**: 如果您的代码涉及自定义类(非 `java.util.Arrays$ArrayList`),确保每个类都有显式的无参构造器。这在引用[^4][^5]中已验证为有效方案。 - **代码示例**: 假设您有一个自定义类 `MyClass`,需添加无参构造器。 ```java public class MyClass { private int id; private String name; // 添加显式无参构造器(必须public或protected) public MyClass() { } // 其他构造器(如有) public MyClass(int id, String name) { this.id = id; this.name = name; } } ``` 在深拷贝前,检查所有涉及的自定义类是否都满足此条件。 3. **使用 FastJSON 的替代深拷贝方法**: 如果上述修改不可行,或您必须处理第三方库返回的不可变对象,改用 JSON 序列化/反序列化作为深拷贝手段。这规避了构造器限制,因为 FastJSON 直接通过字节流重建对象。 - **代码示例**: ```java import com.alibaba.fastjson.JSON; List<String> originalList = Arrays.asList("a", "b", "c"); // 即使不可变,也能处理 // 深拷贝:序列化为JSON字符串,再反序列化 String jsonString = JSON.toJSONString(originalList); List<String> clonedList = JSON.parseObject(jsonString, List.class); ``` 此方法利用了 FastJSON 的通用解析能力,不依赖特定构造器[^2]。 4. **检查 FastJSON 版本和依赖**: 某些 FastJSON 版本(如 1.1.62)可能存在不稳定问题。参考引用[^2],建议降级到稳定版(如 1.1.61)或更新至最新修复版。 - **操作建议**: 在 Maven 项目中,更新 `pom.xml`: ```xml <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.83</version> <!-- 使用最新稳定版 --> </dependency> ``` #### 总结和预防措施 - **根本原因**:FastJSON 要求目标类有可访问的无参构造器,但 `java.util.Arrays$ArrayList` 未提供,导致实例化失败。 - **最佳实践**:在深拷贝场景中,优先使用可变集合类(如 `ArrayList`),并为所有自定义类添加显式无参构造器。定期更新 FastJSON 以避免已知 bug。 - **测试验证**:修改后,运行单元测试确保深拷贝功能正常。例如: ```java @Test public void testDeepClone() { List<String> list = new ArrayList<>(Arrays.asList("test")); Object cloned = CloneUtil.deepClone(list); assertNotSame(list, cloned); // 验证深拷贝成功 } ``` 通过以上步骤,您应能解决 "default constructor not found" 错误。如果问题仍存,请提供更多代码上下文,我会进一步协助!
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值