Sunday, February 28, 2021

Binding variable scope with NOT (!) condition

Let us introduce a NOT (!) operator to the if condition and study the scope of the binding variable in this case. 

Full sample code with NOT condition shown below  


interface Pet {
    default public String color() {
        return this.color();
    }

}

record Dog(String color) implements Pet {

    public void bark() {
        System.out.println("I bark...");
    }
}

record Cat(String color) implements Pet {

    public void meaw() {
        System.out.println("I meaw...");
    }
}

public class Main {

    public static void main(String[] args) {

        Pet p1 = new Dog("White");
        Pet p2 = new Cat("White");

        if (!(p1 instanceof Dog d)) {
            return;
        }
        
        if (!(p2 instanceof Cat c)) {
            return;
        }

        d.bark();
        c.meaw();
    }
}

This code compiles and executes as expected. 

Here binding variables are not accessible inside of the if block because of the not condition and are accessible outside of the if blocks.  

If you observe the code carefully, we are returning immediately if p1 is not Dog and p2 is not Cat. Code flow reaches beyond the if statements if and only if d is Dog and c is Cat. 

It is this unconditional return statement inside of the if block that makes this code work. Had the main method been like this instead, it will not compile

    public static void main(String[] args) {

        Pet p1 = new Dog("White");
        Pet p2 = new Cat("White");

        if (!(p1 instanceof Dog d)) {
            System.out.println("p1 is not Dog");
        }
        
        if (!(p2 instanceof Cat c)) {
            System.out.println("p2 is not Cat");
        }

        d.bark();
        c.meaw();
    }

This code will not compile as the flow would reach d.bark() and c.meaw() even when d and c are not Dog & Cat respectively.

Finally in the below code, we use the binding variable in the else part of the if condition with NOT (!) operator. Here, its assured that d and c are Dog and Cat when the flow reaches their respective else blocks 

    public static void main(String[] args) {

        Pet p1 = new Dog("White");
        Pet p2 = new Cat("White");

        if (!(p1 instanceof Dog d)) {
            System.out.println("p1 is not Dog");
        } else {
            d.bark();
        }
        
        if (!(p2 instanceof Cat c)) {
            System.out.println("p2 is not Cat");
        } else {
            c.meaw();
        }
    }

This will compile and execute as expected.

Sample code used in this post can be downloaded from https://github.com/ashokkumarta/awesomely-java/tree/main/2021/02/Language-Features/Instanceof-Binding-Variable/With-NOT-condition

No comments:

Post a Comment