This page looks best with JavaScript enabled

Improved 'instanceof' operator in Java 14

 ·  ☕ 3 min read

Make your code simpler with implicit casting in improved instanceof operator in Java 14.

Color small blocks with different shapes

The improvements in the instanceof operator (JEP 305 ) are not the most important feature of approaching Java 14. However, it finally implements the syntactic sugar that was available in Groovy for years, so I want to have my readers aware of it and simplify their code (once migrated to Java 14+ :-) ).

“instance of” usually is perceived as a scratch in well designed object oriented system. Nevertheless, there are places where it simplifies the code greatly and/or is the only sensible way to go.

The usual way

Double type checking in Java code is considered as something “normal” (or better something “common”):

if (o insteanceof String) {
    useString((String)o);
}

The same with combined condition checking:

if (o instanceof String && (((String)o).lenght > 10) {
    ...
}

It looks even worse if the class name is longer, e.g. ContentHandlerAlreadyRegisteredException (while received just Exception or Throwable).

The new way (Java 14+)

With fast approaching Java 14 (GA scheduler on 2020-03-17) it becomes much simpler:

if (o instanceof String s) {
    useString(s);
}

The new binding variable (of type String) is available in the if block.

It works also for combined condition checking:

if (o instanceof String s && s.length > 10) {
    ...
}

It can be used also in more complex if..elseif..else constructions. However, in those cases, the new switch..case syntax with the pattern matching allowing - still on the work desk - would be even more handy.

The Groovy way

I wouldn’t be myself, if I skipped a comparison with Groovy :-). In Groovy that double type checking mitigation has been available for years. Even better, thanks to the AST transformation there is no need to define an extra variable. We can just use the original name which is visible with proper typing inside the block:

if (o instanceof String) {
    useString(o)
}

It is dead simple, but I have to admit that an extra binding variable with a custom name might be perceived as something slightly more readable with bigger block of code (which anyway could be usually moved to a separate method).

The switch..case statement is very powerful in Groovy. Checking the instance type is very straightforward:

switch(o) {
    case String:
        println "String"
        break
    case Integer:
        println "Integer"
        break
    default:
        throw new IllegalArgumentException(...)
}

However, even in Groovy 3, there is no type changing withing the scope (available in the if..else). As a result the following works without code completion with dynamic Groovy and fails with @CompileStatic:

void sortItOut(Object o) {

    switch(o) {
      case String:
        println "String: ${o.length()}" //only in dynamic Groovy
        break
      case Integer:
        println "Integer: ${o.longValue()}" //only in dynamic Groovy 
        break
      default:
        throw new IllegalArgumentException(o.toString())
    }
  }

I have to raise a ticket to support that ;-)

Summary

There is a number of small, yet useful changes introduced in Java 12+ (or waiting for implementation in the incoming releases). Multiline string, yield in switch..case or smarter NullObjectExcpetion just to mention a few. Thanks to that Java becomes more and more compact (although Groovy or Kotlin are far ahead on that field).

Lead photo by Alicja, published in Pixabay, Pixabay License.
Share on

Marcin Zajączkowski
WRITTEN BY
Marcin Zajączkowski
Software Craftsman & Solution Architect
An experienced architect aiming for high quality solutions. Very engaged in evangelising Software Craftsmanship, Clean Code and Test-Driven Development as a conference speaker and a trainer. A specialist in Continuous Delivery and Continuous Inspection of Code Quality. An enthusiast of Reactive Systems and broadly defined concurrency.

Besides, open source author and contributor, a proud Linux user.


Don't want to use the Utterance bot? Comments can be also placed directly on GitHub.
What's on this Page