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.
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.