Posted in

Java 的不可为空类型和可为空类型_AI阅读总结 — 包阅AI

包阅导读总结

1.

关键词:Java、Null-Restricted、Nullable Types、JSpecify、Compile-Time Safety

2.

总结:本文介绍了 Java 中有关空值限制和可空类型的内容,包括 JSpecify 项目 1.0.0 版本发布,Draft JEP 8303099 对空值类型的讨论,还提到新特性引入的转换和可能的运行时错误,以及与其他项目的关系和采用建议。

3.

主要内容:

– Java 空值相关

– JSpecify 项目 1.0.0 版本发布,关注静态类型空值状态的类型使用注释。

– Draft JEP 8303099 公开,讨论空值限制和可空类型,处于早期阶段,语法可能改变。

– 空值类型使用

– 有 `Foo!`(空值限制)、` Foo?`(可空)、` Foo`(未指定)三种类型使用方式。

– 引入空值转换,包括放宽和收紧转换,收紧转换可能导致运行时错误。

– 相关项目关系与采用

– 与 JSpecify 工作有重叠,JSpecify 为迁移到语言级空值标记做准备。

– 与 Project Valhalla 有关,对 VM 优化有帮助。

– 采用 JSpecify 时可根据情况灵活处理现有警告。

思维导图:

文章地址:https://www.infoq.com/news/2024/08/null-restricted-java/?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global

文章来源:infoq.com

作者:Ben Evans

发布时间:2024/8/13 0:00

语言:英文

总字数:1032字

预计阅读时间:5分钟

评分:88分

标签:Java,空值性,JEP,JSpecify,编译时安全性


以下为原文内容

本内容来源于用户推荐转载,旨在分享知识与观点,如有侵权请联系删除 联系邮箱 media@ilingban.com

Earlier this week, we reported on the release of version 1.0.0 of the JSpecify project. This release focuses on providing type-use annotations to indicate the nullability status of usages of static types.

Related to this subject, Draft JEP 8303099 was recently made public. This JEP discusses Null-Restricted and Nullable Types, and aims to bring optional nullness-marking to the Java language.

The intent is to add markers – not just annotations – to a type use to specify whether the permissible value set for that use includes null or not. It is important to bear in mind that the proposal is in a very early stage of development (e.g. it doesn’t have an official JEP number yet), so the syntax may well change. Having said this, for now Kotlin-like markers are used, so that, for a type Foo, there are three possibilities for how the type can be used:

  • Foo! is null-restricted – the acceptable values for this use of the type do not include null
  • Foo? is nullable – the acceptable values for this use of the type explicitly includes null
  • Foo does not specify whether or not null is acceptable

The use of bare Foo remains the default, as the meaning of existing code should not change when it’s compiled.

Currently, the proposal calls for every type use to be annotated, i.e. there is no way to mark an entire class or module as null-restricted (as would be possible in JSpecify), although this capability may be added later.

This new feature introduces nullness conversions (similar to widening and unboxing conversions). For example, any of these sorts of assignment are permissible:

  • Foo! to Foo?
  • Foo! to Foo
  • Foo? to Foo
  • Foo to Foo?

as they represent a loosening of constraints – e.g. any null-restricted value can be represented in a nullable use of the type.

There are also narrowing nullness conversions, such as:

These could cause runtime errors, e.g. by trying to load a null from a Foo? into a Foo!. The general strategy here is to treat these cases as compile-time warnings (but not errors) and to include a runtime check that throws a NullPointerException if the nullness bound if violated.

Note that these are basically the easy cases, and more complex cases are possible. For example, when dealing with generics the compiler may encounter situations such as type arguments whose nullness is inconsistent with their declared bounds.

The introduction of null markers provides additional compile-time safety, and allows for a gradual adoption of the markers – first by defining the nullness of types, and then seeking to eliminate compile-time warnings.

InfoQ spoke to Kevin Bourrillion (founder of Google’s core libraries team and now a member of Oracle’s Java language team) — to get more details about the project.

InfoQ: Can you explain your background with the nullness efforts in Java?

Kevin Bourrillion: I co-founded the JSpecify group, and have been one of the main “designers” (defined as “person who bears the burden of driving insanely complicated design decisions to consensus somehow”). I’ve now moved to Oracle but remain involved in approximately the same ways.

InfoQ: How does this JEP overlap with the JSpecify work?

Bourrillion: Eventually we will have a Java with support for nullness markers. JSpecify has done the hard work of nailing down the semantic meanings of the annotations very precisely. This means that whatever upgrade timetable projects choose to adopt will be in a really good position to migrate from JSpecify to language-level nullness markers – in fact that migration should be highly automatable.

InfoQ: There seem to be some similarities between Draft JEP 8303099 and the way that generics was added, way back in Java 5. Is that accurate? This is largely a compile-time mechanism, which is mostly erased at bytecode level, isn’t it?

Bourrillion: Yes, there are some useful parallels there. We think of type erasure and the spectre of “heap pollution” as being unfortunate concessions, but that is what made the feature so *adoptable*. That’s why you almost never have to see a raw type anymore today (I hope!). Now in our case, null pollution will be part of our reality for a long time, but that’s okay! Today it’s all null pollution.

And yes, like generic type information, your nullness annotations are available at runtime via reflection, but are not involved in runtime type checking. I will be interested to see whether anyone builds a bytecode-instrumenter that injects null checks based on our annotations; I can see reasons that might be really useful and reasons it might not be worth the trouble; we’ll have to see.

InfoQ: Null-restriction is also an important topic for Project Valhalla, isn’t it? What can you share about the interaction between this Draft JEP and the ongoing work in that area?

Bourrillion: This is really the same question; Valhalla is just going to build on from that JEP draft you cited. Knowing what can’t be null will help the VM optimize those indirections away.

InfoQ: In the mid to long term, JSpecify should be able to provide an on-ramp to language-level nullability support in Java. This is similar to how it can already be used to alignment with Kotlin’s nullability support. How would you recommend readers go adopt adopting JSpecify today?

Bourrillion: It’s just the JSpecify jar that’s 1.0.0. The specification, which dictates the very precise meaning of the annotations, is still subject to (slight and subtle) changes. So if you put in a lot of work to annotate your codebase today, your code won’t suddenly stop compiling correctly, but after some small spec revisions you might find you want to remove a couple `@Nullable`s here or add a few there.

If adopting nullness analysis in your toolchain today is just too time-consuming because of all the existing warnings you have to clean up, it’s actually a perfectly reasonable approach to spray `@SuppressWarnings` however broadly you need! It’s a bit ugly, but that’s something you can just clean up incrementally over time. Even if that takes a long time, the point is that *new* code will start getting checked today, and that’s the most important code to check anyway.

InfoQ: Thank you!