JDK-8231827 : Implement javac changes for pattern matching for instanceof (Preview)
  • Type: CSR
  • Component: tools
  • Sub-Component: javac
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 14
  • Submitted: 2019-10-03
  • Updated: 2020-10-12
  • Resolved: 2019-11-21
Related Reports
CSR :  
Relates :  
Relates :  
Relates :  
Description
Summary
-------

Support _pattern matching_ by the `instanceof` operator:

    ... o is a variable declared with a general type such as Object ...
    if (o instanceof <type> v) {
        ... use the newly declared variable v
            which refers to the same object as o
            but with a more specific type ...
    }


Problem
-------

The `instanceof` operator is typically used in code like this:

    ... o is a variable declared with a general type such as Object ...
    if (o instanceof <type>) {
        <type> v = (<type>) o;
        ...
    }

The static type of the variable `o` is too general to be useful, but this part of the program is aware that the variable `o` might refer at run time to an object whose type is more specific and thus more useful. To use the object in a type-safe manner, the program must mention the more specific type **three** times: (1) in the `instanceof` operator which examines the object referred to by `o`, (2) in the declaration of a new variable, and (3) in the cast of `o`. This idiom is laborious to write, which increases the chance of a mistake, and, more importantly it is boilerplate which slows down all readers.

Solution
--------

Allow the right hand side of the `instanceof` operator to take a _pattern_ consisting of a type and a variable name. A boolean expression of the form `<expr> instanceof <type> v` is evaluated as follows: if the value of `<expr>` is _dynamically_ an instance of `<type>`, then declare variable `v` whose _static_ type is `<type>` and initialize `v` with the value of `<expr>`.

The scope of variable `v` includes sections of code which are executed if the result of `instanceof` is true. The scope may extend beyond the statement which contains an `instanceof` operator, e.g., beyond an `if` statement whose conditional includes an `instanceof`.

The `<type>` in an `instanceof` is allowed to be non-reifiable if `<expr>` can be cast to `<type>` without unchecked warnings. This applies to both the "traditional" form of `instanceof` (`<expr> instanceof <type>`) and to the "pattern-matching" form of `instanceof` (`<expr> instanceof <type> v`).

The Compiler Tree API is updated to model the pattern-matching form of `instanceof`.

Specification
-------------

The draft specification is attached. It is also available at http://cr.openjdk.java.net/~gbierman/jep305/jep305-20191021/specs/patterns-instanceof-jls.html

The specdiff for the Compiler Tree API change is attached as specdiff.04a.zip. It is also available at http://cr.openjdk.java.net/~jlahoda/8231826/specdiff.04/overview-summary.html

Comments
Moving to Approved.
21-11-2019

Thanks! I've made that fix, uploaded the new version and will finalize the request.
20-11-2019

Hi [~jlahoda], as a code review comment, I'd replace "with-out" by "without" Otherwise, the revision looks okay.
20-11-2019

I've updated the documentation for InstanceOfTree.getPattern, and attached the updated specdiff. It is also available for convenience here: http://cr.openjdk.java.net/~jlahoda/8231826/specdiff.04/overview-summary.html Does that look OK, or are there further changes needed? Thanks.
19-11-2019

While the tree API is terse, the InstanceOfTree.getPattern should document what happens if there is no pattern, etc. Moving to Provisional.
15-11-2019

Correct, this is a preview feature.
05-11-2019

To be clear, this is intended as a preview feature for 14.
01-11-2019