Search code examples
javainstanceof

Java instanceof magic


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.


Solution

  • 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