This time I would like to explain the story that "java.util.Arrays.asList ()
is not an alternative tonew ArrayList <> ()
.
Suddenly, this is an example.
before
List<String> fruts = new ArrayList<>();
fruts.add("apple");
fruts.add("orange");
fruts.add("strawberry");
To
after
List<String> fruts = Arrays.asList("apple", "orange", "strawberry");
** It is dangerous for a reviewer to repair it because it will be shortened. ** **
Do you think this interface will work for you?
void show(List<String> fruts);
There is no problem if you are operating as a collection, but it may cause an error depending on the implementation of the interface.
** As you can see by looking at the instance type, the instance created by java.util.Arrays.asList ()
is not java.util.ArrayList
but java.util.Arrays $ ArrayList
. ** **
If something goes wrong, it's about this difference.
Let's check with the following demo app.
Demo app
package com.example;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Demo {
public static void main(String[] args) {
List<String> fruts1 = new ArrayList<>();
fruts1.add("apple");
fruts1.add("orange");
fruts1.add("strawberry");
show(fruts1);
System.out.println("------------------------------------------------------------");
List<String> fruts2 = Arrays.asList("apple", "orange", "strawberry");
show(fruts2);
}
private static void show(List<String> fruts) {
System.out.println(fruts + " is " + fruts.getClass().toString());
if (java.util.ArrayList.class.isAssignableFrom(fruts.getClass())) {
System.out.println("OK : java.util.ArrayList.class.isAssignableFrom(fruts.getClass())");
} else {
System.out.println("NG : java.util.ArrayList.class.isAssignableFrom(fruts.getClass())");
}
if (java.util.List.class.isAssignableFrom(fruts.getClass())) {
System.out.println("OK : java.util.List.class.isAssignableFrom(fruts.getClass())");
} else {
System.out.println("NG : java.util.List.class.isAssignableFrom(fruts.getClass())");
}
if (java.util.ArrayList.class.isInstance(fruts)) {
System.out.println("OK : java.util.ArrayList.class.isInstance(fruts)");
} else {
System.out.println("NG : java.util.ArrayList.class.isInstance(fruts)");
}
if (java.util.List.class.isInstance(fruts)) {
System.out.println("OK : java.util.List.class.isInstance(fruts)");
} else {
System.out.println("NG : java.util.List.class.isInstance(fruts)");
}
if (fruts instanceof java.util.List) {
System.out.println("OK : fruts instanceof java.util.List");
} else {
System.out.println("NG : fruts instanceof java.util.List");
}
if (fruts instanceof java.util.ArrayList) {
System.out.println("OK : fruts instanceof java.util.ArrayList");
} else {
System.out.println("NG : fruts instanceof java.util.ArrayList");
}
try {
List<String> castObj = (List<String>) fruts;
System.out.println("OK : List<String> castObj = (List<String>) fruts;");
} catch(Exception e) {
e.printStackTrace();
}
try {
List<String> castObj = (ArrayList<String>) fruts;
System.out.println("OK : List<String> castObj = (ArrayList<String>) fruts");
} catch(Exception e) {
e.printStackTrace();
}
}
}
Operation result
[apple, orange, strawberry] is class java.util.ArrayList
OK : java.util.ArrayList.class.isAssignableFrom(fruts.getClass())
OK : java.util.List.class.isAssignableFrom(fruts.getClass())
OK : java.util.ArrayList.class.isInstance(fruts)
OK : java.util.List.class.isInstance(fruts)
OK : fruts instanceof java.util.List
OK : fruts instanceof java.util.ArrayList
OK : List<String> castObj = (List<String>) fruts;
OK : List<String> castObj = (ArrayList<String>) fruts
------------------------------------------------------------
[apple, orange, strawberry] is class java.util.Arrays$ArrayList
NG : java.util.ArrayList.class.isAssignableFrom(fruts.getClass())
OK : java.util.List.class.isAssignableFrom(fruts.getClass())
NG : java.util.ArrayList.class.isInstance(fruts)
OK : java.util.List.class.isInstance(fruts)
OK : fruts instanceof java.util.List
NG : fruts instanceof java.util.ArrayList
OK : List<String> castObj = (List<String>) fruts;
java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList
at com.example.Demo.show(Demo.java:59)
at com.example.Demo.main(Demo.java:17)
Since it is hidden by the interface, it is better to change the recognition that it will always work even if you replace it with ʻArrays.asList`.
** Although there is a fundamental problem with its implementation, ... **
The author ran into " java.lang.ClassCastException: java.util.Arrays $ ArrayList cannot be cast to java.util.ArrayList
"so I decided to write this article.
There was nothing wrong with the interface, so I didn't find it to be an error until runtime.
** The title this time is also correct, "If you replacenew ArrayList <> ()
withjava.util.Arrays.asList ()
, an error will occur depending on the implementation." ** **
(Added on 2018/11/24)
(Method 1) Arrays.asList()Is set in the constructor of ArrayList
List<String> fruts = new ArrayList<>(Arrays.asList("apple", "orange", "strawberry"));
If you point out that you can use ʻArrays.asList ()`, it's best to use it in conjunction with the constructor.
(Method 2) Call a method when creating an instance
List<String> fruts = new ArrayList<String>() {
{
add("apple");
add("orange");
add("strawberry");
}
};
(Method 2) has a slightly unique description method, but this is also grammatically correct.
Recommended Posts