Java instanceof magic

116 views Asked by At

There is such a method:

static void test(List<String> list) {
    System.out.println(list);
    if (!(list instanceof ArrayList<String> arrayList)) return;
    System.out.println(list == arrayList);
    arrayList.add("list");
    System.out.println(arrayList);
    System.out.println(list);
}

Output:

[]
true
[list]
[list]

Please explain how this is possible?

How does this code create another object (arrayList) that is available throughout the method?: list instanceof ArrayList<String> arrayList

Java 17.

1

There are 1 answers

0
MC Emperor On BEST ANSWER

This feature is called pattern matching and was introduced in Java 14 (see JEP 305) and finalized in Java 16 (see JEP 394).

A statement like if (list instanceof ArrayList<String> a) { ... } causes the list variable to be checked whether it is an instance of the ArrayList type, and if it is, then assign its value to a. Now a is available within the if branch.

Equivalent code without the pattern matching feature would look like something like this:

if (list instanceof ArrayList) {
    ArrayList<String> a = (ArrayList<String>) list;
    // do something with a
}

The compiler checks the conditions of the if statement to make sure the pattern matching variable is available in the correct scope. For example, your code contains a negation of the result of the instanceof operator (using the !):

if (!(list instanceof ArrayList<String> arrayList)) {
    return;
}
// Rest of the code

Now the compiler deduces that from the // Rest of the code line, list must be of type ArrayList<Integer>, so the variable arrayList is in scope from here.

More info