7.总结
1.1 知识点

总结主要内容

学习内容回顾

优点

缺点

主要用处

实践预告

7.2 核心要点速览
Json 语法与对象结构
- 整体形态:
{}表示一个对象(一组键值对),[]表示数组;可嵌套,数组里常放多个同结构对象表示列表。 - 键的写法:键必须是双引号字符串;单引号、无引号不符合标准 Json,解析器通常会拒收。
- 值的类型:数字、
true/false、null、双引号字符串、对象、数组;与 C# 字段常见对应是:嵌套类/结构 ↔ 内层{},集合或数组字段 ↔[]。 null:可选子结构可写null(如无武器时weapon为null),代码侧要对可空与默认值有统一约定。- 字典与键类型:对象即「字符串键 → 值」;C# 用整数键的字典落到 Json 里键仍会写成
"1"、"2"这种字符串,反序列化时别假定键还是数值类型。 - 注释与落盘:标准 Json 不含
//、块注释;用jsonc写草稿可以,交给JsonUtility等前必须删注释,否则解析失败。
Excel 表转 Json 工作流
- 目的:表驱动配置,策划维护 Excel,程序读导出的 Json。
- 课堂步骤:Excel 排好列 → 复制 → 网页转换工具粘贴 → 得到文本 → 粘进项目
.json保存。 - 转换后必查:工具可能搞错类型(数字变字符串)、合并单元格、空行、精度等;合入工程前要复查。
- 常见顶层结构:多行配表常是对象数组
[{...},{...}],一行一条逻辑记录。 - 工程化:长期应用脚本、编辑器拓展或构建步骤一键导出,减少手工复制(正文已预告后续方向)。
读取Json文件方法
File.WriteAllText:整文件写入字符串;父目录须已存在,否则抛异常(不会自动建多级目录)。File.ReadAllText:整文件读出为字符串,再交给JsonUtility或LitJson。- 路径习惯:可写存档常用
Application.persistentDataPath;只读配表可用StreamingAssets(注意部分平台只读与加载方式差异)。
| 操作 | 关键类/方法 | 代码示例 | 说明 |
|---|---|---|---|
| 写文件 | File.WriteAllText |
File.WriteAllText(Application.persistentDataPath + "/Test.json", "存储内容"); |
先确保目录存在 |
| 读文件 | File.ReadAllText |
string str = File.ReadAllText(Application.persistentDataPath + "/Test.json"); |
注意编码为 UTF-8 |
JsonUtility
- Unity 内置:
JsonUtility.ToJson、JsonUtility.FromJson(字符串, typeof(T))、JsonUtility.FromJson<T>(字符串)。 - 特性:参与序列化的类型加
[System.Serializable];私有、受保护成员要进 Json 需[SerializeField]。 - 字典:不支持;这类字段不会按字典语义出现在 Json 里(正文示例中字典字段被跳过)。
null子对象:ToJson时引用为null常被写成默认空结构(如"s1":{"age":0,"name":""}),与标准「就是 null」的直觉不一致。- float:可能出现小数打印误差。
- 反序列化容错:Json 少写字段不报错,成员保持默认值。
- 根节点:Json 顶层必须是对象
{};配表是[{...}]时不能FromJson<List<T>>,要壳类如class RoleData { public List<RoleInfo> list; },Json 里用字段包住数组。 - 编码:文件须 UTF-8。
| 操作 | API | 示例 |
|---|---|---|
| 序列化 | ToJson |
string s = JsonUtility.ToJson(obj); |
| 反序列化 | FromJson<T> |
var t = JsonUtility.FromJson<MrTao>(jsonStr); |
LitJson
- 第三方:将源码目录拷入工程,
using LitJson;,用JsonMapper静态方法。 - 序列化 / 反序列化:
JsonMapper.ToJson(obj);强类型用JsonMapper.ToObject<T>(jsonStr);弱类型可先JsonData data = JsonMapper.ToObject(jsonStr),再data["name"]取值。 - 类型规则:不要求
[Serializable];只序列化 public 字段;自定义类型要提供 无参构造函数,否则ToObject<T>失败。 - 字典:键用 string 最稳;Json 键全是带引号的字符串,数值键在文本里也是
"1"这种形式。 - 集合:可直接
JsonMapper.ToObject<RoleInfo[]>(jsonStr)、ToObject<List<RoleInfo>>(jsonStr),贴合 Excel 导出的对象数组。 null:能较直接地保留null语义。- 易错点:工具生成的文本可能在最后一元素后多逗号,整段变非法 Json;编码同样要 UTF-8。
JsonUtility 与 LitJson 对照
| 点 | JsonUtility | LitJson |
|---|---|---|
| 来源 | Unity 内置 | 拷贝源码进项目,占维护成本 |
| 特性 | 要 Serializable / SerializeField |
不要 |
| 私有字段 | SerializeField 可序列化 |
不参与 |
| 字典 | 不支持 | 支持,键用 string |
顶层数组 / List |
须壳类包一层 | 可直接 ToObject<List<T>> 等 |
null |
常落成默认空数据 | 可写 null |
| 无参构造 | 不强制 | 自定义类型必须有 |
选型提示
- 结构简单、不想引第三方、只有「对象套数组」且愿意写壳类,JsonUtility 足够。
- 配表根是数组、要字典、少写特性、
null要准确,正文更常推荐 LitJson;仍要评估源码版本与项目规范。
7.3 面试题精选
基础题
1. 数据持久化到底在解决什么问题
题目
请说明什么是数据持久化,并举例说明「持久化数据」和「仅存在内存中的数据」在程序退出后有什么不同表现。
深入解析
- 持久化:把需要跨运行周期保留的信息写入磁盘、云端存档等介质,下次启动还能读回来。
- 内存数据:随进程销毁而丢失,除非在退出前主动写回持久层。
- 游戏向例子:玩家金币如果只放在运行时的静态变量里,关游戏就没了;写入存档文件或服务器后才算持久化。
答题示例
持久化是让数据在程序关掉之后还在,比如写到本地文件或服务器。
只放在内存里的变量,进程一结束就没了;要保留进度、设置、背包等,必须在合适的时机序列化并落盘或上传。
参考文章
- 1.概述
2. 文件后缀名对实际开发有什么意义
题目
文件名后缀(扩展名)能告诉我们什么?为什么不能仅凭后缀断定文件内容一定正确?
深入解析
- 意义:约定俗成的类型提示,方便系统关联默认程序、团队沟通时一眼知道「大概是配置、贴图还是表格导出」。
- 局限:后缀可以随意改,内容可能是错的编码、截断的文件或根本不是该格式;真正可靠的是打开后按格式规范解析、必要时做校验。
- 和 Json 的关系:
.json只说明「通常按 Json 文本规范去读」,仍要处理非法 Json、编码错误等问题。
答题示例
后缀主要是类型提示,方便识别和关联工具,比如
.json一般当文本结构化数据打开。但不能迷信后缀,内容对不对要靠解析和校验;后缀改个名并不能改变文件真实格式。
参考文章
- 1.概述
3. Json 里键名为什么必须用双引号
题目
标准 Json 中对象的键能否用单引号或不写引号?为什么?
深入解析
- 规范要求键是 JSON String,即双引号包裹、内部按转义规则处理。
- 单引号、裸标识符属于 JavaScript 对象字面量习惯,不是标准 Json;
JsonUtility、多数服务端解析器会判非法。 - 面试加分:提到 RFC 8259 或「与 JS 字面量区分」即可,不必展开所有转义细节。
答题示例
标准 Json 的键必须是双引号字符串。
单引号或不加引号是 JavaScript 写法,很多严格解析器不认;Unity 里用
JsonUtility也会按标准 Json 来解析。
参考文章
- 2.Json文件格式-Json基本语法
4. 标准 Json 文本里能不能写注释
题目
能在 .json 文件里像 C# 一样写 // 或块注释吗?Unity 里用 JsonUtility 读会怎样?
深入解析
- 标准 Json:不允许注释;带
//的文本整体非法。 - **Unity
JsonUtility**:按标准解析,遇到注释会失败。 - 工程习惯:说明写在单独文档或字段里;草稿可用
jsonc高亮,发布资源前删掉注释。
答题示例
标准 Json 没有注释,
JsonUtility也不能读带//的文件。真要说明用额外字段或文档;临时用带注释草稿可以,进包前要清掉。
参考文章
- 2.Json文件格式-Json基本语法
5. JsonUtility 序列化自定义类型时特性怎么加
题目
用 JsonUtility.ToJson 序列化你自己写的 C# 类时,[System.Serializable] 和 [SerializeField] 分别在什么场景必须加?
深入解析
- 参与序列化的类型一般要标
[System.Serializable],否则 Unity 序列化路径不认(最外层有时能凑合,但正文建议该加都加)。 - public 字段默认会进 Json;private / protected 要进 Json 必须加
[SerializeField]。 - 这与 LitJson 不同:LitJson 不认这套特性,只看 public。
答题示例
自定义类要加
[System.Serializable]才能被 JsonUtility 正常序列化。public 字段默认会输出;私有或受保护字段想进 Json 要再加
[SerializeField]。
参考文章
- 4.CSharp操作Json-JsonUtility
进阶题
1. Json 和 Xml 的对比一般会从哪些工程维度切入
题目
如果面试官让你对比 Json 与 Xml,你会从哪些角度回答,并各说一条典型取舍?
深入解析
- 体积与带宽:同样信息量,Json 往往更紧凑,移动端和接口场景更常见;Xml 带大量标签时冗余更明显。
- 人读与手写:Json 花括号与键值对更轻;Xml 标签成对、可带属性,某些配置习惯用 Xml。
- 解析与生态:两种都有成熟解析器;Unity 内置
JsonUtility只面向 Json,Xml 则走另一套 API,选型要和团队规范、已有资产格式对齐。 - 注意:具体项目里还有 Schema、注释、CDATA、混合内容等细节,回答时承认「要看协议与工具链」,比背死结论更稳。
答题示例
会从体积、可读性、解析成本和团队现有格式来比。
Json 一般在网络与轻量配置里更省流量、写法简单;Xml 在需要强 Schema、老系统或特定工具链时仍有地盘。Unity 侧 Json 常用
JsonUtility或第三方库,Xml 是另一套读写路径,选型要跟项目资产和协议一致。
参考文章
- 1.概述
2. Excel 网页转 Json 为什么还要人工检查
题目
把 Excel 复制到在线工具生成 Json,直接进项目可能出什么问题?你会检查哪些方面?
深入解析
- 类型:数字被当成字符串、布尔被当成
"true"文本、浮点精度被截断。 - 结构:合并单元格、空行、表头多行导致键名怪异或缺列。
- 内容:引号、换行、逗号未转义破坏 Json 结构。
- 做法:diff 旧表、抽样跑解析、关键字段做单元测试或校验脚本。
答题示例
自动转换不保证类型和结构都对,可能数字变字符串、合并格搞乱列。
我会肉眼看一遍关键列,能跑解析器加载一遍更好,必要时写小脚本校验 id、数值范围。
参考文章
- 3.Json文件格式-Excel转Json
3. JsonUtility 为什么不能直接把 [{...},{...}] 反序列化成 List
题目
Excel 导出的配表 Json 顶层是对象数组,为什么 JsonUtility.FromJson<List<RoleInfo>>(jsonStr) 会报错?正文里的做法是什么?
深入解析
JsonUtility只把 Json 根节点当「一个对象」来填进一个 C# 类型;根是[开头的数组时,与「单个对象」模型对不上。- 做法:定义
class RoleData { public List<RoleInfo> list; },并把磁盘上的 Json 改成{"list":[...]}这种对象包数组,再FromJson<RoleData>。
答题示例
JsonUtility 要求根是对象,不能直接对顶层数组 FromJson 成 List。
要包一层壳类,Json 里用字段名包住数组,比如
list对应List<RoleInfo>。
参考文章
- 4.CSharp操作Json-JsonUtility
4. LitJson 反序列化为什么强调无参构造函数
题目
LitJson 把 Json 转成自定义类实例时,对类的构造函数有什么要求?没有会怎样?
深入解析
- 反序列化要先
new出目标类型再填字段,LitJson 依赖 无参构造函数 创建实例。 - 只有带参构造、且未显式写无参构造时,
ToObject<T>往往直接异常。 - 带参构造可以保留,但需额外写
public ClassName() { }给反序列化用。
答题示例
LitJson 反序列化要用无参构造先创建对象再填字段。
没有无参构造会报错;可以保留带参构造,但要自己补一个 public 无参构造。
参考文章
- 5.CSharp操作Json-LitJson
深度题
1. 如何把 Excel 到 Json 从手工复制升级成可靠管线
题目
策划继续用 Excel 配表,你希望减少「复制网页→手粘 json」的错误;从工程角度你会怎么设计流程与门禁?
深入解析
- 一键导出:编辑器菜单、命令行或 CI 调用脚本(Python、C#、Node 等)读
xlsx输出.json,版本与输出路径固定。 - 校验:导出后做 Schema 或自定义规则检查(必填列、类型、id 唯一);失败则打断构建。
- 与运行时衔接:约定顶层是数组还是包一层对象,与
JsonUtility/LitJson 的反序列化类型一致;大表考虑分文件或 Addressables。 - 回滚与 diff:Json 进版本库,PR 里能看配表差异;严重错误可快速回滚。
答题示例
我会做一键导出脚本,保存 Excel 就生成 Json,避免人手复制。
导出后加校验:类型、唯一 id、必填字段,不通过不让进包;Json 进 Git 方便 diff。运行时类型跟导出约定对齐,减少反序列化翻车。
参考文章
- 3.Json文件格式-Excel转Json
2. Unity 项目里 JsonUtility 和 LitJson 怎么选
题目
同样读存档或配表 Json,什么情况下你优先 JsonUtility,什么情况下换 LitJson?各说一条风险或成本。
深入解析
- JsonUtility:零第三方、IL2CPP 等场景省心;但字典不支持、顶层数组要壳类、
null与 float 表现要心里有数。 - LitJson:字典、顶层
List/[]、少写特性、null更直观;但要维护拷贝的源码版本,且只能序列化 public、无参构造约束。 - 与正文一致:按需求选,结构复杂时倾向 LitJson;简单对象且想依赖官方 API 时用 JsonUtility。
答题示例
只要简单对象、愿意包一层壳、不想引第三方,用 JsonUtility。
要字典、顶层数组、少写特性、
null要准确,用 LitJson,但要接受拷源码和只序列化 public、无参构造的限制。
参考文章
- 6.CSharp操作Json-JsonUtility和LitJson对比
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com