Nullability in Java
Clement Cherlin
ccherlin at gmail.com
Thu Oct 10 16:37:01 UTC 2024
On Wed, Oct 2, 2024 at 9:30 AM <forax at univ-mlv.fr> wrote:
> ----- Original Message -----
> > From: "Brian Goetz" <brian.goetz at oracle.com>
> > To: "Remi Forax" <forax at univ-mlv.fr>
> > Cc: "valhalla-spec-experts" <valhalla-spec-experts at openjdk.java.net>
> > Sent: Wednesday, October 2, 2024 2:51:34 PM
> > Subject: Re: Nullability in Java
>
> Hello,
>
> > This aligns pretty well with what we’ve been discussing. Your principle
> (1) is
> > key, because this is what enables adding nullity annotations to be
> > source-compatible, and we want to minimize the friction to adding nullity
> > annotations. This means warnings, not errors, backed up by dynamic
> checks.
> >
> > From a language perspective, the states `String` and `String?` are
> semantically
> > identical; the only difference between them is what warnings might be
> emitted.
> >
> > I don’t see the point of excluding locals (or indeed, any) declarations
> from
> > being null-markable. (Some are already implicitly null-restricted, such
> as the
> > throws clause.) Doing so will creates “gates” that impede the flow of
> type
> > information, which would undermine your principle (3).
>
> I don't fully understand what you mean by "gates".
>
> The point is to have the type of locals to change their null-marker
> implicitly.
> I see two reasons why.
>
> 1) If you have a code like:
> String s = f();
> g(s);
>
> If 's' has its null-marker computed automatically, the null marker will
> flow naturally without the user having to update his code each time the API
> of a dependency is updated to use null-marker.
>
> 2) until now, the type of a local variable would never change, we have
> even introduced the concept of binding to explicitly avoid a local variable
> to have its type changed.
> But we also want the nullability part of the type of a local to change
> dependending on the control flow, so having a way to denote the nullability
> on a local's type given that it can changed is weird.
>
> By example, with
> class Foo {
> void m(String! a) { ... }
>
> void main() {
> String? s = ...
> if (s == null) {
> // s is know a String!
> ...
> }
> }
> }
>
> Here, declaring that the type of s is a '?' is not true for the lifetime
> of the variable because the nullability of the type of s can change
> depending on the control flow.
> Avoiding to have a way to denote the nullability of the type of a local
> variable avoid that issue.
>
> Rémi
>
Hi,
The type of a nullable variable does not change even when the nullness of
the value it contains is known. If a variable declared as "String? s"
contains a value that is known to be non-null at a given execution point,
the type of s is still "String?".
Consider the following example:
String? s = maybeNullString();
if (s != null) {
s = null; // legal
}
Inside the if block the _value_ of s is known to be non-null, but the
_type_ of s is still "String?" and not "String!". If the type had changed
to "String!", the commented line would be illegal.
Now consider another example:
void nonNullableStringMethod(String! notNullString) { ... }
void main() {
String? s = maybeNullString();
if (s != null) {
nonNullableStringMethod(s); // legal
}
nonNullableStringMethod(s); // illegal
}
The value s holds is known to be non-null inside the if block, so that
non-null value is a valid argument to nonNullableStringMethod(). But
outside the if block, the value s holds is not known to be non-null, so the
value s holds is not a legal argument to nonNullableStringMethod().
This is different than type information. As you mentioned, type information
is not control-flow-dependent, requiring casting or pattern matching to
change.
CharSequence cs1 = "x";
if (cs1 instanceof String) {
nonNullableStringMethod(cs1); // illegal
}
The variable cs1 has type CharSequence, not String, and Java does not use
instanceof to perform flow-dependent type inference (it could, but it
doesn't).
CharSequence cs2 = "x";
if (cs2 instanceof String s) {
nonNullableStringMethod(s); // legal
}
Rebinding declares a new variable with the specified type.
Cheers,
Clement Cherlin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20241010/4b83282d/attachment.htm>
More information about the valhalla-spec-observers
mailing list