Friday, March 26, 2021

Implementing equals(Object) with instanceof Pattern Matching

Pattern matching for the instanceof operator was introduced as a preview feature with JDK 14 and was finalized with JDK 16. Because instanceof pattern matching is finalized for JDK 16, it is not surprising to now see changes being made to the JDK to take advantage of pattern matching for the instanceof operator. These changes to the JDK to leverage instanceof pattern matching can provide ideas and examples for where to begin applying this in our own code. In this post, I look at the use of instanceof pattern matching in implementation of the ubiquitous equals(Object) methods.

In a message posted to the core-libs-dev OpenJDK mailing list related to a code review for JDK-8263358 ("Update java.lang to use instanceof pattern variable"), Brian Goetz provided a reminder that a standard approach used in implementation of equals(Object) can now be modified to take advantage of pattern matching for instanceof.

In the message, Goetz uses an example of how we have often implemented equals(Object) (but using instanceof pattern matching in this example consistent with the past):

if (!(o instanceof Key that)) return false;
return name == that.name && Arrays.equals(ptypes, that.ptypes);

Goetz points out that this can now be written with a single statement, in this manner:

return (o instanceof Key that)
   && name == that.name
   && Arrays.equals(ptypes, that.ptypes);

Goetz's message concludes with this:

The use of "if it's not, return false" is a holdover from when we couldn't express this as a single expression (which is almost always preferable), which means we had to fall back to control flow. Now we don't have to.

A new commit was made based on Goetz's feedback and that commit is Commit e9d913152cefda827e01c060a13f15eacc086b33. One can review the several changes associated with this commit to see multiple statements converted into single statements in the various equals(Object) methods.

Being able to use instanceof pattern matching to implement equals(Object) with one fewer statement is a small improvement that is nevertheless welcome.

No comments: