写点什么

新的 JEP 草案发布,将在 Java 中引入可选空值标记

Ben Evans

  • 2024-09-14
    北京
  • 本文字数:2027 字

    阅读完需:约 7 分钟

新的JEP草案发布,将在Java中引入可选空值标记

之前我们报道了 JSpecify 1.0.0 版本的发布。这个版本主要引入了类型使用注解,用于指示静态类型的空值状态。


与之相关的是,JEP 8303099 草案 最近已对外公布。这个 JEP 探讨了 Null-Restricted 和 Nullable 类型,旨在将可选的空值标记引入到 Java 中。


该提案的核心是在类型使用上引入明确的标记——不仅仅是注解,指明在特定使用场景中允许的值是否包括。需要注意的是,这个提案目前还处于初步开发阶段(例如,它尚未获得正式的 JEP 编号),因此其语法在未来有可能会发生变化。尽管如此,目前的提案借鉴了 Kotlin 的标记方式,因此,对于类型,有三种使用方式:


  • Foo! 表示 Null-Restricted——这种类型可接受的值不包括;

  • Foo? 表示 Nullable——这种类型可接受的值包括 ;

  • Foo 没有明确指定是否接受。


使用未加修饰的 Foo 作为默认选项,这样做是为了保持现有代码在编译时的语义不变。


目前,该提案要求对于每一个类型的使用都进行注解,即尚不支持将整个类或模块标记为 Null-Restricted(比如像 JSpecify 那样),尽管这个功能可能会在未来引入。


这个新特性引入了一种空值转换机制(类似扩展和拆箱转换)。例如,以下这些赋值是被允许的:


  • 将 Foo! 赋值给 Foo?;

  • 将 Foo! 赋值给 Foo;

  • 将 Foo? 赋值给 Foo;

  • 将 Foo 赋值给 Foo?。


这种属于约束放宽——例如,任何 Null-Restricted 的值都可以被放在 Nullable 的值中。


也有窄化空值的转换,例如:


  • 将 Foo? 赋值给 Foo!;

  • 将 Foo 赋值给 Foo!。


这些可能会导致运行时错误,例如尝试将 null 从一个 Foo? 赋值给 Foo!。通常的策略是将这些情况视为编译时警告(而不是错误),并引入运行时检查,如果检测到违反空值界限,就抛出 NullPointerException。


请注意,这些例子仅展示了一些基础情况,实际当中可能存在更为复杂的情形。例如,在处理泛型时,编译器可能会面临类型参数的空值属性与其声明的界限不匹配的情况。


引入空标记不仅增强了编译时的安全性,还支持逐步采用的策略——首先定义类型允许的空值,然后通过解决编译时警告来逐步优化代码。


InfoQ 采访了 Kevin Bourrillion(谷歌核心库团队创始人,现在是 Oracle Java 语言团队成员),深入了解该项目的更多细节。

InfoQ:你能介绍一下你在 Java 空值处理方面的专业背景和相关经验吗?

Bourrillion: 我与其他一些人共同创立了 JSpecify 小组,并一直是主要的“设计师”(这个角色可以被理解为在推动复杂设计决策过程中达成共识的人)。尽管现在我加入了 Oracle,仍然以相似的方式继续参与项目。

InfoQ:这个 JEP 与 JSpecify 的工作有哪些重叠的地方?

Bourrillion: 最终我们将拥有一个支持空值标记的 Java 版本。JSpecify 在精确定义注解语义的含义方面完成了艰巨的任务。这意味着无论项目选择怎样的升级时间表,都将处于一个非常有利的位置,能够从 JSpecify 的注解平滑迁移到语言级别的空值标记——实际上,这种迁移应该是高度自动化的。

InfoQ:JEP 8303099 草案和 Java 5 中添加泛型的方式似乎有一些相似之处。这么说对吗?都是一种编译时机制,大部分信息会在字节码级别被擦除,是这样吗?

Bourrillion: 是的。我们认为类型擦除和所谓的“堆污染”是不得已的妥协,但正是这种设计让特性更容易被广泛采用。这也正是为什么现在几乎看不到原始类型的原因(至少我希望如此!)。空值污染将是一个长期存在的问题,但这没关系!现在全部都是关于空值污染。


正如泛型类型信息一样,空值注解在运行时通过反射发挥作用,但不参与运行时类型检查。我很好奇是否会有人基于我们的注解开发一个注入空检查的字节码工具;我认为这可能会非常有用,但也可能存在不值得投入精力的情况;我们只能等待并观察市场和技术社区的反应。

InfoQ:空值限制也是 Project Valhalla 的一个重要话题,不是吗?你能分享一些这个 JEP 草案与 Valhalla 项目正在进行的工作之间的相互影响和互动吗?

Bourrillion: 这实际上是同一个问题;Valhalla 项目是在这个 JEP 草案的基础上进一步构建的。知道哪些值不能为空将有助于虚拟机优化这些间接调用。

InfoQ:从中期到长期来看,JSpecify 应该能够为 Java 语言级别的空值支持提供一个平滑的过渡路径。它已经能够与 Kotlin 的空值支持相协调。对于开发者采用 JSpecify,你有哪些建议?

Bourrillion: JSpecify 目前处于 1.0.0 版本,尽管注解的定义已经相当精确,但规范仍有可能会经历一些细微的调整。所以,如果你现在开始对你的代码库进行注解,你的代码不太可能突然无法编译,但在一些小的规范修订后,你可能需要在某些地方移除或增加一些 @Nullable 注解。


如果你发现将空值分析集成到现有的工具链中过于耗时,因为你需要清理所有的警告,那么采用@SuppressWarnings注解是完全可以接受的!虽然这可能看起来不够优雅,但你可以随着时间的推移逐步对它们进行清理。即使这可能需要很长时间,但关键在于新代码从现在开始就有了空值检查,而这才是最需要关注的部分。


InfoQ:感谢接受采访!


查看英文原文:

https://www.infoq.com/news/2024/08/null-restricted-java/

2024-09-14 00:0910947

评论

发布
暂无评论
发现更多内容

出海新模式:从蔚赫信息收购德国博世LABCAR HiL 技术看如何通过海外IP并购实现全球化布局

千流出海

千流出海

滴滴是如何落地eBPF技术的?

滴滴技术

云原生 eBPF&Linux

海量数据×桂林银行 | 满足金融用户稳健周密需求,做好国内数据库演进的实践担当 openGauss

daydayup

Burp Suite 几个基本工具的使用

QE_LAB

渗透测试 测试工具 安全测试

从电商指标洞察到运营归因,只需几句话?AI 数智助理准备好了!

Kyligence

数据分析 数智助理

年内实现全面自动驾驶?快来恶补一下自动驾驶技术吧!

博文视点Broadview

Hello,Vector DB|可能是最易上手的 Faiss 教程

Zilliz

Faiss Milvus Zilliz 向量数据库 zillizcloud

openGauss数据库源码解析系列文章——事务机制源码解析(三)

daydayup

运用事件与定时器实现字幕滚动效果(Qt开发)

芯动大师

Docker学习路线11:Docker命令行

小万哥

Java c++ Python Go Docker

Last Week in Milvus

Zilliz

非结构化数据 Milvus Zilliz 向量数据库

openGauss数据库源码解析系列文章——事务机制源码解析(一)

daydayup

数字化转型与架构-规划篇|殊途同归的解决方案框架

数字随行

数字化转型

Coral Finance 将为 Zepoch 节点空投,Nautilus生态空投季开启

BlockChain先知

2023-07-25:你驾驶出租车行驶在一条有 n 个地点的路上 这 n 个地点从近到远编号为 1 到 n ,你想要从 1 开到 n 通过接乘客订单盈利。你只能沿着编号递增的方向前进,不能改变方向 乘

福大大架构师每日一题

福大大架构师每日一题

Oracle单表数据量大的优化思路

zhengzai7

oracle 分区

TypeScript 玩转类型操作之字符串处理能力

小乌龟快跑

JavaScript typescript 类型推断

使用show effective grants查看权限

GreatSQL

greatsql greatsql社区

UE像素流送是什么?像素流推流原理介绍

3DCAT实时渲染

云流化 实时渲染云

openGauss 开源社区再次入选“科创中国”开源创新榜

daydayup

openGauss加入 CNCF Landscape

daydayup

Deel、Whatnot、Nowports,YC 净收入最高公司生意秘诀

B Impact

提示工程101|与 AI 交谈的技巧和艺术

SEAL安全

人工智能 AI LLM 提示工程 企业号 7 月 PK 榜

海量数据×桂林银行 | 满足金融用户稳健周密需求,做好国内数据库演进的实践担当#openGauss

daydayup

openGauss数据库荣获中国计算机学会(CCF)科技成果特等奖

daydayup

openGauss数据库源码解析系列文章——事务机制源码解析(四)

daydayup

Nautilus Chain:主权模块化区块链的早期实践

西柚子

Java Web应用开发案例|使用监听器统计Web站点的在线用户数

TiAmo

Java web 用户统计 开发案例

Java中的JDBC的使用方法有哪些?

java易二三

Java 编程 程序员 计算机

新的JEP草案发布,将在Java中引入可选空值标记_大前端_InfoQ精选文章