Java: Pattern Matching for instanceof

☞ This article describes a preview feature, JEP draft: Pattern Matching for instanceof (Preview 2). If you want to play around with this, download and install JDK 15 available here and use the --enable-preview . This article will be updated as the specification evolves.

Pattern matching for instanceof allows you to bind a new variable as part of the expression:

if (obj instanceof String New variable declared… str ) { System.out.println( "obj is a String of length " + str .length() …that can be used as a String ); }

Scope of instanceof variable

The scope of the the bound variable depends on the context in which the expression is written. The compiler performs a (simple) flow analysis and allows you to use the variable where the instanceof check holds true.

In the if statement in the example above, the scope of str is the true-branch.

if (obj instanceof String str) { scope of str … }

By negating the check, the scope becomes the false branch:

if (!(obj instanceof String str)) { … } else { scope of str … }

The variable is also used in the part of the expression where it is true. This means that you can implement a simple equals method without explicit casting:

boolean equals(Object o) { return o instanceof Point p && p.x == x && p.y == y ; }

Similarity to local variable initialization

Being able to introduce a variable as part of an expression like this is a unique feature. The scoping rules however, follow the same principles as the local variable initialization analysis performed by the compiler. Compare for example the first example in this article with this snippet:

String str ; if ( obj instanceof String && ( str = ( String ) obj ) != null ) { }

As you can see, the accessibility of str is in practice the same, although the error message is ofcourse different.

Future functionality

What’s described in this article can barely be classified as pattern matching. As described in the JEP however, this new instanceof functionality will be expanded to support nested matching for record types (JEP 359), and possibly other patterns.