liveBook · Manning

Instanceof operator

As explained in 100 Java Mistakes and How to Avoid Them

The instanceof operator tests whether an object or reference is compatible with a specified runtime type or constructor according to the programming language’s rules.

In Java, `instanceof` tests whether an object matches a type at runtime, including subclasses. This makes it useful before a downcast, but it also means broad checks can overlap narrower ones. In an `if`/`else if` chain, only the first true branch runs. section 3.2 section 5.5

Put specific types before supertypes

`BigInteger` and `BigDecimal` are both `Number` values. Testing `obj instanceof Number` first therefore captures them before their specialized conversions can run. Test `BigInteger` and `BigDecimal` first, then use `Number` as the fallback; the same most-specific-first ordering applies to pattern-matching `switch` cases. section 3.2

BigInteger toBigInteger(Object obj) {
  if (obj instanceof Number)
    return BigInteger.valueOf(((Number) obj).longValue());
  if (obj instanceof BigInteger) 
    return (BigInteger) obj;
  if (obj instanceof BigDecimal) 
    return ((BigDecimal) obj).toBigInteger();
  return BigInteger.ZERO;
}

This ordering is faulty: the initial `Number` check makes the later `BigInteger` and `BigDecimal` branches unreachable for their intended inputs. section 3.2

Avoid `instanceof` mistakes by checking the runtime hierarchy and branch order:

  • Place subtype checks before a check for their shared superclass or interface. section 3.2
  • Use `instanceof` rather than an exact `getClass()` comparison when subclasses should be accepted. section 9.6
  • Use exact class checks only when exact-class behavior is intentional; an abstract class can never equal an instance's runtime class. section 9.6
  • Confirm “always true” or “always false” analyzer findings with a unit test when the warning seems doubtful. section 9.6

`getClass() == SomeType.class` and `obj instanceof SomeType` are not interchangeable. The former requires the exact runtime class, while the latter accepts subclasses. For final classes they differ chiefly in null handling; for extensible types, choose according to whether subclass instances belong in the same behavior. section 9.6

An `instanceof` check can make a cast safer, but it should not compensate for an unnecessarily broad declared type. When a value is known to have a more concrete type, declaring that type can remove the cast instead. section 5.5

How 100 Java Mistakes and How to Avoid Them covers it

How deep it goes
Explains subtype matching through branch-order failures and contrasts it with exact runtime-class comparisons.
Examples
Uses BigInteger and BigDecimal conversion, date conversion, ArrayList checks, and Calendar instances.
What it assumes
Assumes Java familiarity with casts, class hierarchies, conditional chains, and runtime classes.
What you can do after
Diagnose/debug with it by finding unreachable type branches and choosing subclass-compatible versus exact-class tests.
How it connects
Connects runtime type checks with downcasting, inheritance, getClass(), pattern-matching switch, and static analysis.

Also explained in

Compare how 2 books explain instanceof operator →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of 100 Java Mistakes and How to Avoid Them. The section links point to the parts of the book it draws on.