BadInstanceof
instanceof used in a way that is equivalent to a null check.

Severity
WARNING
Tags
Simplification

The problem

Flags instanceof checks where the expression can be determined to be a supertype of the type it is compared to.

JLS 15.28 specifically calls instanceof out as not being a compile-time constant expression, so the usage of this pattern can lead to unreachable code that won’t be flagged by the compiler:

class Foo {
  void doSomething() {
    if (this instanceof Foo) { // BAD: always true
      return;
    }
    interestingProcessing();
  }
}

In general, an instanceof comparison against a superclass is equivalent to a null check:

foo instanceof Foo
foo != null

Pattern-matching instanceofs introduce some extra complexity into this. It may be tempting to use an instanceof check to define a narrowly-scoped local variable which gets reused within an expression, for example,

return proto.getSubMessage() instanceof SubMessage sm
    && sm.getForename().equals("John")
    && sm.getSurname().equals("Smith");

We feel this urge should be resisted. While this is a clever trick to avoid an extra line, it is not a true instanceof check, and declaring a variable normally is clearer:

SubMessage sm = proto.getSubMessage();
return sm.getForename().equals("John") && sm.getSurname().equals("Smith");

Suppression

Suppress false positives by adding the suppression annotation @SuppressWarnings("BadInstanceof") to the enclosing element.