An instanceof type pattern tests a reference and binds a narrowed variable only on control-flow paths where the test succeeded.
Java instanceof patterns: keep a narrowed value inside its valid scope
Operational contract
The method rejects every value that is not a RefundEvent, including null. After the throwing guard, the compiler knows refund is a RefundEvent for the remaining method body. No explicit cast is needed. Pattern matching does not validate the record's business fields; this code checks the amount separately. This narrow branch is appropriate when an API receives a mixed event type. For a closed set of event kinds, a sealed hierarchy can give stronger compile-time coverage.
Failure case
An event router receives an Object representing a refund of 2,300 cents. It returns 2,300. A String or null fails at the routing boundary instead of becoming a zero-value refund, which would hide a bad integration payload.
Java code
public class RefundPatternGate {
public record RefundEvent(String receiptId, long cents) { }
public static long acceptedCents(Object event) {
if (!(event instanceof RefundEvent refund))
throw new IllegalArgumentException("Expected refund event");
if (refund.cents() < 0 || refund.cents() > 47_000)
throw new IllegalArgumentException("Refund outside policy");
return refund.cents();
}
}Performance and ownership cost
The runtime type test and field checks take O(1) time and no collection storage. The pattern variable is a reference to the same object; it is not a copy or a separate validated instance.
Common Mistakes
- Do not assume the pattern variable exists on the branch where the test is false.
- Do not treat type matching as validation of record fields.
- Do not map unsupported input to a plausible business value without an explicit rule.
Connected lessons
- Java 21 pattern switch: exhaustive branches and null policy
- Java sealed types: restrict a domain’s direct variants
- Java casts and numeric conversion: discarded bits and checked references
- Java interface defaults: resolve a two-parent method conflict
- Java compact record constructors: normalize before field assignment
- Java switch expressions: return one value from every state
- Java sealed hierarchies: switch over permitted request kinds
- Java generics and language contracts quiz
- Advanced Java
