写点什么

新的 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:0910708

评论

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

HDFS的垃圾桶机制

五分钟学大数据

hadoop 4月日更

想来百万流量技术公众号发布文章吗? InfoQ 开放内容平台了!

xiaotan

InfoQ 的朋友们 热门活动

入门物联网嵌入式才是关键!

cdhqyj

技术 编程语言 物联网 嵌入式 系统

想来百万流量技术公众号发布文章吗? InfoQ 开放内容平台了!

InfoQ写作社区官方

热门活动

云原生势不可挡,华为云GaussDB加速企业数字化转型

华为云开发者联盟

华为云 GaussDB

LeetCode题解:剑指 Offer 49. 丑数,三指针,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

Flume高阶自定义组件

大数据技术指南

大数据 flume 4月日更

JVM-技术专题-方法区中常量池分析

洛神灬殇

JVM 常量池

小厂逆袭美团|5年经验|一二三面经,已拿offer|

Java架构追梦

Java 架构 面试 美团Offer

「 留言参与 」—— InfoQ 写作平台【 1 周年盛典 】

InfoQ写作社区官方

1 周年盛典 热门活动

PHP自动加载原理

Sakura

4月日更

全球案例 | NTT:Atlassian 帮助我们重塑危机中的可能性

Atlassian

敏捷 团队协作 数字化转型 Atlassian Jira

非科班毕业生,五面阿里:四轮技术面+HR一面已拿offer

码农之家

Java 编程 程序员 互联网 面试

最全 MongoDB 基础教程

若尘

数据库 mongodb mongo

7年Java经验|面20+家公司|已拿16个offer|面经总结|

Java架构追梦

Java 架构 面试 20+大厂面经

HikariCP-技术专题-配置介绍和使用

洛神灬殇

APM-技术专题-监控系统选型

洛神灬殇

APM 监控

应对海量时序数据,华为云GaussDB(for Influx)有妙招

华为云开发者联盟

云原生 数字化转型 时序数据 华为云GaussDB

第一篇测试

童童

架构训练营

阿里巴巴云原生 etcd 服务集群管控优化实践

阿里巴巴云原生

容器 运维 云原生 k8s 存储

硬核!阿里内部这份《Java面试核心知识手册》在Github上已获赞高达89.7K!

Java架构之路

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

Modbus协议在串行链路上的实现

不脱发的程序猿

通信协议 物联网常用协议 4月日更 Modbus 串行通信

1小时破千万点击量!阿里巴巴首发:Java核心框架指导手册

Java架构追梦

Java 阿里巴巴 架构 面试 核心框架

Android面试送分题:大厂经典高频面试题体系化集合,实战篇

欢喜学安卓

android 程序员 面试 移动开发

android热修复基本原理,15分钟的字节跳动视频面试,满满干货指导

欢喜学安卓

android 程序员 面试 移动开发

iOS--面试题:多线程

ios 面试 多线程

智慧城市:大数据运营中心 IOC —— Web GIS 地图应用

一只数据鲸鱼

WebGIS ioc 数据可视化 智慧城市 数据运营

《采访彩食鲜 CTO 乔新亮:如何从一名程序员晋阶为CTO》(采访提纲)

石云升

28天写作 4月日更 调查采访能力考核

博云入选2021爱分析·产业数字化厂商全景报告

BoCloud博云

云计算 云原生 PaaS 博云

重读《重构2》- 提炼变量

顿晓

重构 4月日更

Modus串行链路系统电气特性:2线-Modus、4线-Modus、RS232-Modus和RS485-Modus的特性

不脱发的程序猿

通信协议 4月日更 Modus 串行链路 RS232、RS485

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