[The following is only of interest to those concerned about very fine details
of the JLS; no change to the language is proposed here.]
Currently in the JLS we build the mechanics of pattern matching directly on top
of casts. For example, in 14.30.2 (emphasis added):
- A value v that is not the null reference matches a type pattern of type T if
v **can be cast to** T without raising a ClassCastException; and does not match
otherwise.
This was useful as it made real the equivalence:
if (e instanceof T t) { … } <—> if (e instanceof T) { T t = (T)e; …}
But, in terms of the JLS, there are some shortcomings. First, the semantics of
pattern matching above should really refer to casting _conversions_ rather than
casts. Oh well. But digging a little deeper there are further issues. Section
5.5 defines cast _contexts_ - the places where cast conversions can be applied.
Except that it is all a little misleading. It currently says "Casting contexts
allow the operand of a cast expression (15.16) to be converted to the type
explicitly named by the cast operator.” but that’s not really true as we just
agreed that we want to cover the new pattern matching contexts too. Sigh. It
also gets complicated by the fact that we don’t want to use all the cast
conversions either - we exclude any narrowing reference conversions that are
unchecked AND we actually don’t use any of the cast conversions that deal with
primitive types (these are all excluded by the definition of “applicability” of
patterns). We deal with this by introducing the concept of "checked cast
convertible" in 5.5 and relying on the fact that we only consider applicable
patterns.
This is all okay, but with the changes proposed by JEP 455 (Primitive types in
patterns, instanceof, and switch) coming real soon now, it is time to tidy up
this treatment and set a proper foundation.
To this end, we propose to add a new, seventh sort of context to the list given
in the introduction to chapter 5 - called *testing contexts* - to handle
pattern matching, and also define a notion of *test conversion*. As an example,
the rule from the semantics of pattern matching given above, can now be
expressed as:
- A value v that is not the null reference matches a type pattern of type T if
v can be converted by testing conversion to the target type T without raising a
ClassCastException; and does not match otherwise.
I have made a spec change document so you can see the details of this change
that will appear in the Java SE 22 Edition of the spec:
https://cr.openjdk.org/~gbierman/new-context/specs/new-context.html
Again, I repeat, this is purely a presentational change at the level of the
spec - the Java language itself is unchanged.
Thanks,
Gavin