Gson反序列化报错:Expected BEGIN_ARRAY but was BEGIN_OBJECT 求助
Gson反序列化报错:Expected BEGIN_ARRAY but was BEGIN_OBJECT 解决办法
问题根源
你当前的序列化代码是循环将单个CPU对象写入文件,导致outputGson.txt中是多个独立JSON对象直接拼接(无数组包裹、无逗号分隔),属于非法JSON数组格式。而反序列化时你告诉Gson要解析成ArrayList<CPU>,它期望的是标准JSON数组(以[开头、]结尾,元素用逗号分隔),因此触发语法错误。
解决方案
方案1:修改序列化代码(推荐)
直接序列化整个List<CPU>,生成标准JSON数组格式,这样原反序列化代码无需改动即可正常工作。
修改后的序列化代码:
public void serializeCpu(String filename) throws IOException { Writer writer = new FileWriter(filename); Gson gson = new GsonBuilder().setPrettyPrinting().create(); // 直接序列化整个List,而非循环写入单个对象 gson.toJson(list, writer); writer.close(); }
生成的outputGson.txt会变成标准JSON数组:
[ { "name": "CPU.1", "speed": 2.4, "ram": 8.0, "cache": 2.2 }, { "name": "CPU.2", "speed": 2.0, "ram": 16.0, "cache": 4.0 }, { "name": "CPU.3", "speed": 1.6, "ram": 4.0, "cache": 1.3 } ]
方案2:适配现有非法格式(仅当无法修改文件时使用)
如果无法重新生成outputGson.txt,可以通过流式读取或字符串分割的方式,逐个解析每个独立的JSON对象:
方式A:字符串分割(简单场景)
String inputString = readWithScannerGson("outputGson.txt"); Gson gson = new Gson(); List<CPU> outputList = new ArrayList<>(); // 清理空白字符后,按"}{"分割每个对象(正则匹配:前面是},后面是{的位置) String[] jsonObjStrings = inputString.replaceAll("\\s+", "").split("(?<=\\})(?=\\{)"); for (String jsonStr : jsonObjStrings) { CPU cpu = gson.fromJson(jsonStr, CPU.class); outputList.add(cpu); }
方式B:JsonReader流式读取(更可靠)
使用Gson的JsonReader流式处理非严格格式的JSON,避免字符串分割可能出现的异常:
try (JsonReader reader = new JsonReader(new FileReader("outputGson.txt"))) { Gson gson = new Gson(); List<CPU> outputList = new ArrayList<>(); reader.setLenient(true); // 允许解析非严格格式的JSON // 循环读取直到文档结束 while (reader.peek() != JsonToken.END_DOCUMENT) { CPU cpu = gson.fromJson(reader, CPU.class); outputList.add(cpu); } } catch (IOException e) { e.printStackTrace(); }
总结
优先选择方案1,生成标准JSON数组是通用做法,后续维护和兼容性更好;仅当无法重新生成文件时,再考虑方案2的适配逻辑。
内容的提问来源于stack exchange,提问作者aeioeaieo
相关产品推荐
相关产品推荐

