java.util.Arrays.asList () is not a replacement for new ArrayList <> ()

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)

Answer when you really want to define and initialize List in one line

(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

java.util.Arrays.asList () is not a replacement for new ArrayList <> ()
Java Calendar is not a singleton.
[For programming beginners] What is a method?
A memo for myself that object-oriented is something
rails new app is not created with app name
The public key for jenkins-2.249.1-1.1.noarch.rpm is not installed