前言:
前几天在工作的时候遇到了一个Java实体类序列化出现了$符号的问题,当时也不知道是怎么回事,后来查阅了网上的资料后发现是序列化的引用问题。
小Demo:
实体类如下:
#省略gate和set方法
public class Student {
private int id;
private String name;
private List<String> habits;
}
测试代码:
List<Student> students = new ArrayList<>();
Student studentA = new Student();
studentA.setId(1);
studentA.setName("A");
List<String> habitsList = new ArrayList<>();
habitsList.add("篮球");
habitsList.add("羽毛球");
habitsList.add("乒乓球");
studentA.setHabits(habitsList);
students.add(studentA);
students.add(studentA);
students.add(studentA);
System.out.println(JSON.toJSONString(students));
代码运行结果:
[{"habits":["篮球","羽毛球","乒乓球"],"id":1,"name":"A"},{"$ref":"$[0]"},{"$ref":"$[0]"}]
why,当时我也是一脸闷逼吧,为什么会这样子,后来才发现引用的分类是可以分为如下两类
1: 重复引用
一个对象重复多次出现
2:循环应用
互相引用,即JSON序列化出现$的情况,处理不好可能会报StackOverflowError异常。
因此,如何关闭呢,这里与alibabaJSONObject为例,其他序列化类其实也是大同小异啦?
全局关闭,直接设置序列化方式
JSONObject.DEFAULT_GENERATE_FEATURE = SerializerFeature.DisableCircularReferenceDetect.getMask();
System.out.println(JSON.toJSONString(students));
临时关闭,暂时变化序列化方式
JSON.toJSONString(students,SerializerFeature.DisableCircularReferenceDetect)
上述两种方式,都可以序列化为如下
[{"habits":["篮球","羽毛球","乒乓球"],"id":1,"name":"A"},{"habits":["篮球","羽毛球","乒乓球"],"id":1,"name":"A"},{"habits":["篮球","羽毛球","乒乓球"],"id":1,"name":"A"}]