Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The instanceof operator is a binary relational operator used to test whether the runtime type of an object reference is assignment-compatible with a specific class, subclass, or interface. It evaluates the type relationship dynamically at runtime and returns a boolean value.

Syntax

objectReference instanceof Type

Evaluation Rules

The operator evaluates the relationship based on strict type-checking rules:
  1. Subtyping and Inheritance: It returns true if the actual object referred to by objectReference is an instance of Type, or an instance of any direct or indirect subclass/subinterface of Type. Equivalently, for any non-null reference, it returns true if (Type) objectReference would succeed without throwing a ClassCastException.
  2. Null References: If objectReference evaluates to null, the instanceof operator strictly returns false. It never throws a NullPointerException.
  3. Compile-Time Constraints: The Java compiler enforces static type checking on the operator. If the declared type of objectReference and the target Type exist in disjoint inheritance hierarchies (meaning neither can possibly be a subtype of the other), the compiler rejects the expression and throws an inconvertible types error.

Generics and Type Erasure

Due to type erasure, the Java runtime does not retain generic type parameters. Consequently, the instanceof operator cannot be used with parameterized types at runtime, as the JVM cannot verify the generic type argument. Attempting to do so results in a compile-time error. Instead, instanceof must be used with raw types or unbounded wildcards.
Object obj = new ArrayList<String>();

// boolean isStringList = obj instanceof List<String>; // Compile-time error
boolean isList = obj instanceof List<?>;               // Valid: unbounded wildcard
boolean isRawList = obj instanceof List;               // Valid: raw type

Mechanical Example

Number num = Integer.valueOf(42);

boolean isInteger = num instanceof Integer; // true: runtime type is Integer
boolean isNumber  = num instanceof Number;  // true: Integer is a subtype of Number
boolean isObject  = num instanceof Object;  // true: Integer inherits from Object
boolean isDouble  = num instanceof Double;  // false: runtime type is Integer, not Double
boolean isNull    = null instanceof String; // false: null references always return false

String text = "Java";
// boolean isInt = text instanceof Integer; // Compile-time error: inconvertible types

Pattern Matching for instanceof (Java 16+)

Starting in Java 16, the operator was enhanced with pattern matching, which fuses the type test, the type cast, and variable declaration into a single expression.

Syntax

objectReference instanceof Type patternVariable

Mechanics of Pattern Matching

If the instanceof evaluation returns true, the runtime automatically casts the objectReference to the target Type and binds it to the patternVariable. The patternVariable is subject to flow scoping. Its scope is strictly limited to the execution paths where the instanceof condition is guaranteed to be true.
Object obj = "Technical Documentation";

// 'str' is only in scope if the evaluation is true
if (obj instanceof String str) {
    int len = str.length(); // No explicit cast required
}

// 'str' is out of scope here
Flow scoping also applies to compound boolean expressions, provided the short-circuiting logic guarantees the type test succeeded before evaluating the right-hand operand:
// Valid: 'str' is guaranteed to be bound if the right side evaluates
if (obj instanceof String str && str.length() > 5) {
    // ...
}

// Compile-time error: 'str' might not be bound if the left side is false
// if (obj instanceof String str || str.length() > 5) { ... }
Master Java with Deep Grasping Methodology!Learn More