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

