Fastjson1 常见问题与陷阱

作为 Java 开发中最常用的 JSON 库之一,Fastjson1 以其高性能和易用性赢得了大量用户。但如果你不是经常使用这个库在使用时往往会遇到一些“坑”。本文将梳理几个最常见的问题与陷阱,并配以代码示例,帮助你快速避坑。

自动类型转换引发异常

Fastjson1 默认会尝试自动进行类型转换,这可能导致意外的异常。

// 错误的示例
String json = "{\"age\":\"20\"}";
class User {
    public int age;
}
User user = JSON.parseObject(json, User.class);
// 正常输出 age=20,因为 String "20" 被自动转为 int

但当你期望严格类型匹配时,这个特性可能隐藏错误。例如:

String json = "{\"age\":\"twenty\"}";
// 抛出异常: JSONException: can not cast to int, value twenty

建议:使用 JSON.parseObject(json, User.class, Feature.DisableFieldSmartMatch) 开启严格模式。

字段名大小写敏感问题

在 Fastjson 1.x 中,默认情况下其行为表现为对大小写不敏感。
具体来说,在将 JSON 字符串反序列化(Parse)为 Java 对象时,Fastjson 默认会尝试匹配属性名,即使大小写不一致通常也能成功转换。

String json = "{\"UserName\":\"Alice\"}";
class Person { 
    public String username; 
}
Person p = JSON.parseObject(json, Person.class);
System.out.println(p.username); // 输出 Alice

Fastjson 默认确实会忽略字段名的大小写差异进行匹配,所以例子中即使 "UserName" 和 "username" 大小写不同,仍然能正确赋值,输出 Alice 而不是 null。

即使你添加@JSONField(name = "userName") 注解的方式它也是大小写不敏感的。

日期格式化陷阱

Fastjson1 对日期的处理非常灵活,但容易出错:

// 默认输出为时间戳
Date now = new Date();
String json = JSON.toJSONString(now);
System.out.println(json); // 输出: 1778640624808 (时间戳)

需要指定格式

JSON.DEFFAULT_DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"; // 全局设置
String json = JSON.toJSONString(now, SerializerFeature.WriteDateUseDateFormat);
System.out.println(json); // 输出: "2026-05-13 10:53:20"

或者使用 @JSONField(format = "yyyy-MM-dd") 注解在字段上。

循环引用导致栈溢出

当对象之间存在互相引用时,直接序列化会抛出 StackOverflowError

class Node {
    public String name;
    public Node parent; // 可能形成循环
}

Node a = new Node();
a.name = "A";
a.parent = a; // 自己引用自己

String json = JSON.toJSONString(a); // 栈溢出!

解决方法:使用 SerializerFeature.DisableCircularReferenceDetect 关闭循环引用检测(但会失去引用关系),或者给对象实现 Serializable 并合理设计模型。

泛型类型擦除

Fastjson1 在处理 List、Map 等泛型时,需要正确处理类型擦除:

// 错误写法
String json = "[1,2,3]";
List list = JSON.parseObject(json, List.class); // 返回的是 List<Object>,元素是 Integer,但不是 List<Integer>

正确做法

Type type = new TypeReference<List<Integer>>() {}.getType();
List<Integer> list = JSON.parseObject(json, type);

对于复杂嵌套泛型(如 Map<String, List<User>>),务必使用 TypeReference

小结

Fastjson1 虽然强大,但使用时需要关注:

  • 类型转换的严格性
  • 字段名大小写与映射
  • 日期的序列化格式
  • 循环引用处理
  • 泛型类型的正确解析