文章摘要
该JEP提案为Java平台定义了一个简单标准的JSON解析与生成API,旨在无需外部库即可处理JSON文档,降低编码复杂度。该API遵循RFC 8259标准,保持小巧易学,避免复杂配置和扩展功能,使代码简洁可读,便于探索未知JSON文档。
文章总结
好的,这是根据您提供的英文内容,使用中文重新陈述的文章主要内容,已保留关键细节并删减了与主题无关的内容。
JEP 540:简易 JSON API(孵化器)主要内容
摘要
本提案旨在为 Java 平台定义一个简单、标准的 API,用于解析和生成 JSON 文档,从而避免依赖外部库。该 API 旨在让许多 JSON 处理任务只需少量代码即可完成。这是一个孵化中的 API。
目标
- 为 Java 平台提供一种标准方式,以低代码量处理符合 RFC 8259 标准的 JSON 文档。
- 保持 API 小巧、简单且易于学习。仅提供严格遵循 RFC 8259 所需的数据类型和操作,以促进机器间的通信。避免引入多种解析配置、语法扩展、数据绑定和流式处理等特性。
- 确保从已知结构的 JSON 文档中导航和提取数据的代码简单且可读。
- 支持对不熟悉的 JSON 文档进行快速探索。API 应提供在出错时能快速失败并给出清晰错误信息的方法。
- 确保能够弹性处理缺失或意外的值,因为 JSON 文档结构可能随时间演变。
- 使 JDK 自身具备解析和生成 JSON 文档的能力。
非目标
- 不旨在创建一个取代现有成熟 JSON 库的 API。
动机
JSON 在现代计算中无处不在。虽然 Java 生态中有众多成熟的 JSON 库,但很多时候我们只需要执行简单的任务,例如从 JSON 文档中提取一些数据。Python 或 Go 完成此类任务的代码很简单,Java 代码也应该同样简单。例如,计算美国国家气象局 REST API 响应中一组预报温度的平均值,应该能用简单的 Java 代码完成,而无需安装外部库。
此外,一个标准的 JSON API 将为 JDK 自身进一步使用 JSON 铺平道路,例如用于配置文件。JDK 目前使用的属性文件格式无法表达结构化数据,而 JSON 可以自然地表示数组等结构。
描述
该 API 围绕 JsonValue 接口组织,该接口代表一个 JSON 值。JSON 语法有四种基本类型(字符串、数字、布尔值、null)和两种结构类型(对象、数组)。JsonValue 接口有六个对应的子接口:JsonString、JsonNumber、JsonBoolean、JsonNull、JsonObject 和 JsonArray。JsonValue 接口是密封的,确保任何实例都属于这组固定的子类型。
解析和导航: 使用 Json.parse() 方法解析 JSON 文档,返回一个 JsonValue 树。解析是严格的,必须符合 RFC 8259,不支持尾随逗号、注释和重复的成员名称。可以通过 get(String) 和 get(int) 方法从对象和数组中检索值。如果类型错误或成员/元素不存在,会抛出 JsonValueException。
转换为 Java 值: 通过 asString()、asInt()、asLong()、asDouble()、asBoolean()、asMap() 和 asList() 等方法将 JSON 值转换为对应的 Java 类型。如果转换不成功,会抛出 JsonValueException。
处理文档演变: 当 JSON 文档的结构或内容发生变化时(例如,成员名称不存在或值类型改变),访问或转换方法会抛出 JsonValueException。异常信息会描述从文档根节点到意外值的路径及其在文档中的位置。
处理可选成员和空值: 使用 tryGet(String) 方法安全地获取可能不存在的对象成员,它返回一个 Optional。使用 tryValue() 方法处理可能为 JSON null 的值,如果值为 JsonNull,则返回空的 Optional。
生成 JSON 文档: 调用 JsonValue 的 toString() 方法可以生成紧凑的 JSON 字符串。Json.toDisplayString() 方法可以生成美化打印(pretty-printed)的 JSON 字符串。
JSON 数字: API 提供了 asDouble()、asInt() 和 asLong() 方法用于常见的数字转换。如果数值超出范围或无法精确表示,会抛出异常。对于需要无损处理任意精度数字的场景,可以将 JSON 数字转换为 java.math.BigDecimal。
替代方案
- 提供完整功能集: 被否决。数据绑定和流式处理等特性会增加巨大的 API 体积、实现和维护成本,而许多用例并不需要它们。
- 集成外部 JSON 库: 被否决。这会引发许可、治理、兼容性和维护方面的复杂问题。
- 不作为: 被否决。这无助于实现“让简单任务更容易完成”的更大目标,尤其是对于简单程序和新手而言。
测试
将进行严格测试,确保只能解析和生成 RFC 8259 的规范形式,并利用现有的 JSON 解析测试套件。
风险与假设
- 假设输入的 JSON 文档可以完全加载到内存中。
- 存在新 API 可能与现有外部 JSON 库在应用中混用,导致混乱的风险,但利大于弊。
- 在孵化期间,将收集更多关于生成和转换 JSON 文档的用例信息,以完善 API。
评论总结
根据评论内容,总结如下:
主要观点与论据:
支持纳入标准库(评分:无,作者:gavinray、IanGabes、MeteorMarc)
- 认为JSON已成为基础数据格式,标准库支持可减少外部依赖
- 引用:"With a JSON module, you finally won't NEED to rely on external deps to build a basic JVM web service without pain."(gavinray)
- 引用:"Many languages have json marshalling and unmarshalling in their standard libs, e.g. C#, golang, python."(MeteorMarc)
API设计争议(评分:无,作者:dfabulich、nikeee)
- 批评API过于繁琐,缺乏简洁性
- 引用:"There's gotta be a better way! ... Why can't I write this? JsonObject.of(Map.of("providers", List.of("SUN", "SunRsaSign", SunEC"))));"(dfabulich)
- 质疑类型安全:".get(string) 或 .get(int) 应仅存在于JsonObject和JsonArray上"(nikeee)
功能缺失担忧(评分:无,作者:esprehn)
- 不支持注释将限制其替代配置文件的能力
- 引用:"Not supporting comments will be a mistake that haunts this API. ... This seems to repeat the same mistakes of Go's built in JSON library"(esprehn)
异常处理争议(评分:无,作者:jonenst)
- 对使用非受检异常表示意外
- 引用:"I find it very surprising that they went for unchecked exceptions. ... especially given the pushback from openjdk members against jackson3 moving to unchecked exception"(jonenst)
数值精度优势(评分:无,作者:q3k)
- 赞赏任意精度数字处理
- 引用:"Happy to see that numbers are arbitrary width/precision until explicitly cast by the user. This goes against so many other JSON libraries that will always cast all numbers to double"(q3k)
平衡性说明: 评论呈现明显分歧:支持者强调减少外部依赖和标准化优势,批评者则关注API设计缺陷、功能缺失和异常处理问题。部分评论(如whartung)持中立态度,认为虽有用但现有库已足够。