写点什么

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:057887

评论 1 条评论

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

朱嘉明:比特币开创人类新型财富实验

CECBC

数字货币

发布两小时,霸榜GitHub!Spring Boot实战文档

Java 编程 程序员 架构师

科技进化的终点,与荣耀全场景的起点

脑极体

filecoin云算力软件开发|filecoin云算力APP系统开发

系统开发

趋势预测:2021年五大流行的编程语言

薇薇

Java c php JavaScript Python PEP

filecoin矿机系统开发|filecoin矿机软件APP开发

系统开发

聊聊 Python 自动化脚本部署服务器全流程(详细)

星安果

Python 自动化 服务器 部署

全凭阿里大牛总结的Java面试笔记,首战成功拿蚂蚁offer

Java架构之路

Java 程序员 架构 面试 编程语言

直击面试!阿里技术官手码12W字面试小册在Github上爆火

Java架构之路

Java 程序员 架构 面试 编程语言

以数字人民币为契机 推动人民币国际化进程

CECBC

金融

epoll源码分析以及在Redis中的实现

Linux服务器开发

redis 后端 epoll web服务器 Linux服务器开发

打卡学习VBA和PYTHON week01

小怪兽

IT蜗壳教学

如何评估需求优先级?

石云升

项目管理 28天写作 职场经验 管理经验 3月日更

收藏!这些IDE使用技巧,你都知道吗

xcbeyond

IDEA 技巧 3月日更

霸榜Git!2021年阿里巴巴Java面试权威指南(全彩版)

Java 程序员 面试 架构师

寻找被遗忘的勇气(十八)

Changing Lin

3月日更

图解垃圾算法,No,捡垃圾算法

叫练

GC算法 引用计数法 标记清除法

"无密码时代"已经来临!

龙归科技

身份认证

声网Agora发布创业支持计划:聚合50+合作伙伴、11项资源扶持创业者

ToB行业头条

声网 Agora

php 再上热搜!swoole 创始人投出反对票,质疑 php 协程最新提案

薇薇

php 编程 新特性 php扩展

炸裂,IBM系统架构师居然把自己15年Java经验整合成一本小说?

Java架构师迁哥

DCache 分布式存储系统|Set, ZSet 缓存模块的创建与使用

TARS基金会

nosql 缓存 分布式 MySQL 高可用 TARS

JDBC—往MySQL中写入Blob数据时,出现错误:com.mysql.jdbc.PacketTooBigException: Packet for query is too large (5724349 > 1048576)

打工人!

Java MySQL JDBC Blob

一周信创舆情观察(3.8~3.14)

统小信uos

filecoin挖矿软件开发|filecoin挖矿APP系统开发

系统开发

uni-app跨端开发H5、小程序、IOS、Android(二):开发工具HBuilderX使用技巧

程序员潘Sir

微信小程序 uni-app App 3月日更 Hbuilderx

全球案例 | Infobip :这家估值十亿美元的公司像初创企业一样规模化发展,像大型企业一样标准化

Atlassian

DevOps Agile Atlassian Jira ITSM

低代码/无代码,作为IT开发界的“新英雄”它究竟有何神技?

优秀

低代码 无代码开发

StarRocks在中移物联网PGW实时会话业务领域的应用

StarRocks

大数据 数据分析 物联网 IoT OLAP

2021年新兴的十大区块链技术趋势

CECBC

数字技术

霸榜Git!2021年阿里巴巴Java面试权威指南(泰山版)

Java架构之路

Java 程序员 架构 面试 编程语言

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