4月10-12日 QCon 北京,与全球 140+ 顶尖工程师共同解构 AI 时代的技术浪潮! 了解详情
写点什么

JSpecify 1.0.0 发布,助力 Java 空值处理

Ben Evans

  • 2024-09-24
    北京
  • 本文字数:2492 字

    阅读完需:约 8 分钟

JSpecify 1.0.0发布,助力 Java 空值处理

JSpecify 发布首个版本 JSpecify 1.0.0,其使命是为 JVM 语言定义一组通用的注解类型,用于改善静态分析和语言互操作性。


达成共识的项目和团对包括:


  • OpenJDK

  • EISOP

  • PMD

  • Android、Error Prone、Guava(谷歌)

  • Kotlin、IntelliJ(JetBrains)

  • Azure SDK(微软)

  • Sonar

  • Spring


参与 JSpecify 的成员们承诺,他们的项目将在源代码层面保持向后兼容性。这意味着他们不会重命名 jar 包中的注解、移动它们或做出其他导致更新后代码编译失败的变更。换句话说,依赖 JSpecify 是安全的,它不会以任何破坏应用程序代码的方式做出变更。


这个首发版本专注于引入类型使用注解,用于指明静态类型的空值状态。主要用途预计将集中在变量、参数和返回值上,也适用于任何需要在概念上追踪空值情况的场景。


然而,某些应用场景可能未通过“概念意义”验证——例如,你仍然无法实现类似 Foo extends @Nullable Bar 这样的语法。

空值问题与空值检查器的相关背景


空值问题一直是 Java 生态系统中的一个备受争议的话题。开发者应该尽可能免受 NPE 的影响,因为目前可能导致 NPE 的大量用例应该在构建时被排除。


然而,这个充满希望的理念在实践中遭遇了一些挑战,尤其是由于 Java 现有的一些限制:


  • 由来已久,在很大程度上早于编程语言中的非空值概念。

  • 对向后兼容性的承诺。


因此,要以一种既一致又不会破坏现有代码的方式将空值意识融入到编程语言中变成了一项极为艰巨的挑战。


尽管如此,还是有人做过尝试——最著名的可能是 JSR 305,它持续了好几年,但最终在 2012 年进入休眠状态,未能实现全面标准化的目标。


在此之后,很多公司和项目继续开发并使用他们自己的空值注解实现。其中一些项目主要是为了解决他们自己的用例,而其他一些则致力于提供更广泛的适用于 Java 应用程序的解决方案。


值得一提的是 Kotlin,它将空值意识直接融入到类型系统中。Kotlin 做了一些假设,例如,String 表示一个值不能为 null,如果要表示可空值,开发者需要明确使用 String?。这在很大程度上取得了成功,至少只要程序是用纯 Kotlin 编写的。


Java 开发者有时候也会表达他们“对 Kotlin 空值处理功能的渴望”,但正如 Kotlin 文档明确指出的那样,这里有许多微妙之处,特别是当与 Java 代码互操作时。


目前,在纯 Java 领域,大多数项目在处理空值问题时都是将空值状态视为静态分析工具(构建时检查器)处理的附加信息。通过添加额外的注解让检查器减少或消除在运行时可能出现的 NPE。


不同项目对应该提供多大程度的“健壮性保证”有着不同的理念。健壮性并非没有成本——它可能导致更复杂的代码、更大的迁移工作量以及需要处理的误报数量增加,所以不是每个开发者都追求全面而彻底的健壮性保证。


JSpecify 标志着一种统一各种方法的尝试,初始目标相对谦逊——1.0.0 版本只定义了四个注解:


  • @Nullable

  • @NonNull

  • @NullMarked

  • @NullUnmarked


前两个可用于特定的类型使用(例如参数定义或方法返回值),后两个则有更广泛的应用范围。它们为 Java 类型系统提供了一种声明式的空值意识。


一个常见的用例是在你需要添加空值信息的模块、包或类型声明上使用 @NullMarked 注解。这可以大大减少工作量,因为它指明所有未明确标注的类型使用都是非空的。然后,需要可空值的特殊情形可以明确地标注为 @Nullable。


目的是让最终用户采用(或继续使用)其中一个参与 JSpecify 的项目——不同的项目有不同的成熟度。例如,IntelliJ 支持 JSpecify 注解,但还不完全支持泛型。


还有一个参考检查器可供使用,但它主要是为参与 JSpecify 的项目设计的,不是直接面向应用程序开发者。


还有一个问答深入探讨了更深层次的设计和技术细节。


InfoQ 采访了 JSpecify 的关键开发者之一——Juergen Hoeller(Spring Framework 项目负责人)。


InfoQ:请介绍一下你在 JSpecify 项目中参与空值处理的情况。


Hoeller:我和 Sebastien Deleuze 一起设计 Spring Framework 5 中的空值处理,因此参与了 JSpecify。


InfoQ:你能否介绍一下 JSpecify 在你的项目中的应用方式,以及它对项目的重要性体现在哪些方面?


Hoeller:Spring Framework 及其产品组合中的很多项目在 2017 年采用了默认非空的设计原则,这在很大程度上是受到了 Kotlin 的启发,但也为基于 Java 的项目(结合 IntelliJ IDEA 和像 NullAway 这样的工具)提供了显著的好处。


这在我们的公共 API 中有所体现,应用程序开发者可以推敲参数和返回值的空值状态。它也深入到我们的内部代码库中,帮助我们验证空值假设和断言是否与实际代码流程保持一致。这对我们自身的内部设计和维护工作带来了极大的益处。


虽然 JSR 305 注解在工具中得到了广泛的应用,但从未正式完成。Spring 自己的注解使用 JSR 305 作为元注解,以提高工具的可发现性,从而迅速获得了 IntelliJ IDEA 和 Kotlin 的支持。


我们参与 JSpecify 源于我们对现有注解的不满,我们希望为注解语义和工具支持提供一个战略性的路径,让我们能够在遵循严格空安全性的同时演进我们的 API 和代码库。


InfoQ:发布 1.0.0 版本花了 6 年时间。你认为是什么导致花了这么长时间?


Hoeller:尽管在 Spring 中,我们对 JSpecify 的应用主要集中在参数、返回值以及字段值上,看起来相当直接,但整个问题域本身是相当复杂的。JSpecify 的目标是支持泛型,这被证明是一个特别棘手的任务。JSpecify 1.0 考虑到了众多利益相关者的要求,要达成广泛共识并不容易。


InfoQ:如果 JSpecify 取得成功,未来会怎样发展?


Hoeller:首先,JSpecify 完全有能力取代 JSR 305,成为工具以及开源框架和库通用注解的新标准。在 JDK 17 等当前广泛使用的基线上获得这样的支持至关重要,因为开源生态系统的大部分将在未来的许多年里继续依赖这样的基线。即使在接下来的几年中使用更新版本的 Java 和 Kotlin,基于 JDK 17 的框架和库仍将被广泛使用,JSpecify 可以随着它们的需求而演进。


InfoQ:JSpecify 接下来需要解决哪些问题?


Hoeller:从 Spring 的角度来看,我们迫切需要官方对元注解的支持,以便我们能够使用 JSpecify 的元注解而非 JSR 305 元注解来声明我们自己的空值注解。


InfoQ:感谢接受采访!


原文链接:

https://www.infoq.com/news/2024/08/jspecify-java-nullability/

2024-09-24 08:057070

评论 1 条评论

发布
用户头像
“参与 JSpecify 的成员们承诺,他们的项目将在源代码层面保持向后兼容性。”句中的“向后兼容性”,本意是指向以前的版本兼容。向以前翻译成向后,个人觉得不妥。不如换成“向下兼容性”,因为版本号往往是往上增长的,更符合中文读者的理解。
2024-09-24 08:51 · 广东
回复
没有更多了
发现更多内容

落实《中国人民银行业务领域数据安全管理办法》,极盾科技是怎么做的?

极盾科技

数据安全

软件测试 | 日志的删除

测吧(北京)科技有限公司

测试

让数据管理由繁至简的低代码开发平台

力软低代码开发平台

MIAOYUN获评“2023年度一云多芯稳定安全运行优秀案例”

MIAOYUN

解决方案 信创 中国信通院 信创云 可信云大会

基于低代码平台快速搭建应用

互联网工科生

低代码 低代码开发 JNPF java低代码开发平台

代码随想录Day36 - 贪心算法(五)

jjn0703

利用文心千帆打造一个属于自己的小师爷

为自己带盐

大语言模型 文心千帆

GPTCache 悬赏令!寻找最佳捉虫猎手,豪华赏格等你来拿!

Zilliz

Zilliz AIGC ChatGPT LLM gptcache

如何通过Python线程池实现异步编程?

互联网工科生

Python 线程池

AI+游戏,内容生产力的又一次变革

澳鹏Appen

人工智能 AR vr 生成式AI 游戏AI

直击运维痛点,大数据计算引擎 EasyMR 的监控告警设计优化之路

袋鼠云数栈

监控 监控告警

平台工程社区:与全球 2w+ 早期实践者同行

杨振涛

DevOps 云原生 社区 平台工程 平台工程师

如何解决大量小文件传输慢的问题

镭速

小文件传输

saas堡垒机定义以及优势简单说明-行云管家

行云管家

SaaS 堡垒机 saas堡垒机

如何为物联网设备注入“华为云+鸿蒙DNA”?

华为云开发者联盟

云计算 后端 华为云 华为云开发者联盟 企业号 8 月 PK 榜

第二期开源答题挑战,看看你是什么级别吧!

开放原子开源基金会

开源 挑战 答题

LeetCode题解:剑指 Offer 56 - I. 数组中数字出现的次数,哈希表,JavaScript,详细注释

Lee Chen

JavaScript LeetCode

作为CTO,我真正想要的可观测性平台

JainChen

开发者 监控 可观测性

使用低代码平台提高生产力

树上有只程序猿

低代码 生产力 全栈开发 JNPF

站在营销的角度浅谈直播行业

山东布谷网络科技

直播 直播app 直播APP源码

软件测试 | mysqlhotcopy(MyISAM表热备份工具)

测吧(北京)科技有限公司

测试

铜锁 SM2 算法性能优化实践(二)|快速模约减算法实现

铜锁开源密码库

开源 开发者 算法 同态加密 密码学

安全文件传输的重要性及其对企业的影响

镭速

文件传输

校源行|开放原子开源社团(山东大学)授牌仪式隆重举行

开放原子开源基金会

开源 山东大学

校源行 | 2023年开放原子校源行开源大使培训圆满结束,考试时间正式公布

开放原子开源基金会

开源

全新升级!腾讯云大数据ES Serverless服务开启日志分析新体验

腾讯云大数据

elastic

软件测试 | mysqlshow(数据库对象查看工具)

测吧(北京)科技有限公司

测试

首期"源规律"开源公益课程正式上线

开放原子开源基金会

开源 合规 法律法规

定档!WAVE SUMMIT 2023@全球开发者,8月16日北京见!

飞桨PaddlePaddle

人工智能 百度 paddle 飞桨 百度飞桨

JSpecify 1.0.0发布,助力 Java 空值处理_编程语言_InfoQ精选文章