Scope of Pattern Variables – Object-Oriented Programming

Scope of Pattern Variables

We first examine the scope of a pattern variable in an if-else statement. If the instanceof pattern match operator returns true in the conditional of an if statement, the pattern variable is introduced and its scope is the if block. Not surprisingly, this is also the case for the if-else statement. The pattern variable is not accessible in the else block.

Click here to view code image

IStack stack = new SafeStack(20);
if (stack instanceof SafeStack safestack) {
  System.out.println(safestack.isFull());   // Pattern variable in scope.
} else {

  System.out.println(safestack.isEmpty());  // Compile-time error!
}

It is important to keep in mind that the instanceof pattern match operator introduces a pattern variable if and only if it returns true. In the if-else statement below, the if block is only executed if the conditional is true—that is, if the instanceof pattern match operator returns false. In that case, no pattern variable is introduced, and thus no pattern variable is ever accessible in the if block. However, if the conditional is false, the instanceof pattern match operator must be true, and thus introduces a pattern variable that is guaranteed to be accessible in the else block.

Click here to view code image

IStack stack = new SafeStack(20);
if (!(stack instanceof SafeStack safestack)) { // Logical complement operator (!)
  System.out.println(safestack.isFull());      // Compile-time error.
} else {
  System.out.println(safestack.isFull());      // Pattern variable in scope.
}

In fact, if the if block does not complete normally (e.g., by executing a return, a break, or a continue statement) as shown at (1), the pattern variable introduced is accessible in the else block and in code after the if-else statement.

Click here to view code image

IStack stack = new SafeStack(20);
if (!(stack instanceof SafeStack safestack)) {
  System.out.println(“No safestack here”);
  return;                                     // (1) Does not complete normally.
} else {
  System.out.println(safestack.isFull());     // Pattern variable in scope.
}
System.out.println(safestack.isEmpty());      // Pattern variable still in scope.

The instanceof pattern match operator can also introduce a pattern variable in certain boolean expressions. The conditional in the if statement below uses the conditional-AND operator (&&). The short-circuit evaluation of the && operator ensures that the right-hand operand is only executed if the left-hand operand evaluates to true, thereby introducing the pattern variable that is then in scope in the right-hand operand. The pattern variable will be in scope in the if block if the conditional evaluates to true—that is, both operands of the && operator return true. Applying the logical complement (!) operator to the conditional expression below works the same way as we have seen earlier with the if-else statement.

Click here to view code image

IStack stack = new SafeStack(20);
if (stack instanceof SafeStack safestack && safestack.isFull()) {
  System.out.println(“safestack is full”);

  Object obj = safestack.pop();
}

The conditional-OR operator (||) does not introduce a pattern variable in the if block. Because of short-circuit evaluation of the || operator, the right-side operand of the conditional is only evaluated if the left-side operand is false, but then no pattern variable has been introduced in the boolean expression by the instanceof pattern match operator.

Click here to view code image

IStack stack = new SafeStack(20);
if (stack instanceof SafeStack safestack || safestack.isFull()) { // Compile-time
                                                                     error.
  System.out.println(“safestack is full”);
  Object obj = safestack.pop();                             // Compile-time error.
}

Using the same pattern variable in instanceof expressions below results in a compile-time error, as this is analogous to redeclaring a local variable.

Click here to view code image

IStack stack = new SafeStack(20);
if (stack instanceof SafeStack safestack &&  // Compile-time error!
    stack instanceof ISafeStack safestack) { // Duplicate variable safestack
  System.out.println(safestack);
}

The instanceof pattern match operator can be used in the conditional (ternary) operator, and it’s semantics are analogous to those of the if-else statement:

Click here to view code image

IStack stack = new SafeStack(20);
boolean result = stack instanceof SafeStack safestack ? safestack.isEmpty()
                                                     : false;

The instanceof pattern match operator can also introduce a pattern variable in loops—for example, in for and while statements. This allows conditional processing of objects where loop termination is controlled by the boolean value of the instanceof pattern match operator and the pattern variable referring to the next object for processing.

Using the instanceof pattern match operator makes the code concise and safe, as it combines three tasks into a single operation: subtype checking, reference casting, and assignment to a local variable.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *