Hacker News 中文摘要

RSS订阅

JEP 540:简单JSON API(现处于孵化阶段) -- JEP 540: Simple JSON API (Now in Incubator)

文章摘要

该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 接口有六个对应的子接口:JsonStringJsonNumberJsonBooleanJsonNullJsonObjectJsonArrayJsonValue 接口是密封的,确保任何实例都属于这组固定的子类型。

解析和导航: 使用 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 文档: 调用 JsonValuetoString() 方法可以生成紧凑的 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。

评论总结

根据评论内容,总结如下:

主要观点与论据:

  1. 支持纳入标准库(评分:无,作者: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)
  2. 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)
  3. 功能缺失担忧(评分:无,作者: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)
  4. 异常处理争议(评分:无,作者: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)
  5. 数值精度优势(评分:无,作者: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)持中立态度,认为虽有用但现有库已足够。