приведение Arrays.asList к исключению: java.util.Arrays $ ArrayList нельзя преобразовать в java.util.ArrayList - PullRequest
38 голосов
/ 10 июля 2011

Я новичок в Java и пытаюсь понять, почему первый фрагмент кода не вызывает этого исключения, а второй вызывает.Поскольку массив строк передается в Arrays.asList в обоих случаях, не должны ли оба фрагмента создавать исключение или не создавать исключение?

Exception in thread "main" java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList

Первый фрагмент (не вызывает исключений):

ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String line = "a,b,cdef,g";
String delim = ",";
String[] pieces = line.split(delim);
stuff.add((ArrayList<String>) Arrays.asList(pieces));

Второй фрагмент (вызывает исключение):

ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((ArrayList<String>) Arrays.asList(titles));

Если уместно, я используюJavaSE 1.6 в Eclipse Helios.

Ответы [ 7 ]

30 голосов
/ 10 июля 2011

Для меня (с использованием Java 1.6.0_26) первый фрагмент дает то же исключение, что и второй.Причина в том, что метод Arrays.asList(..) возвращает только List, но не обязательно ArrayList.Поскольку вы на самом деле не знаете, какую ( реализацию ) List этот метод возвращает, ваше приведение к ArrayList<String> небезопасно.В результате он может работать, а может и не работать, как ожидалось.С точки зрения стиля кодирования хорошим решением было бы изменить объявление stuff на:

List<List<String>> stuff = new ArrayList<List<String>>();

, что позволит добавлять все, что выходит из метода Arrays.asList(..).

10 голосов
/ 10 июля 2011

Проблема в том, что вы указали, что ваш список содержит ArrayLists - и, как следствие, нет других реализаций списка . Arrays.asList() возвращает собственную реализацию List, основанную на реализации параметра массива, который не может быть ArrayList. Это твоя проблема.

В более широком смысле, у вас есть проблема классического стиля кода: вы должны ссылаться на абстрактные интерфейсы (т.е. List), а не на конкретные реализации (например, ArrayList). Вот как должен выглядеть ваш код:

List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = { "ticker", "grade", "score" };
stuff.add((List<String>) Arrays.asList(titles));

Я проверил этот код, и он работает без ошибок.

10 голосов
/ 10 июля 2011

Если вы сделаете это, вы не получите CCE:

ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add(new ArrayList<String>(Arrays.asList(titles)));

Как ясно указывает на ошибку, класс java.util.ArrayList отличается от вложенного статического класса java.util.Arrays.ArrayList. Отсюда и исключение. Мы преодолеваем это, оборачивая возвращаемый список, используя java.util.ArrayList.

8 голосов
/ 06 января 2015

Нет необходимости кастовать вручную. Этот простой код может вам помочь,

List stuff = new ArrayList();
String line = "a,b,cdef,g";
String delim = ",";
stuff.addAll(Arrays.asList(line.split(delim)));
1 голос
/ 25 января 2016

Если вы хотите использовать ваше свойство как ArrayList <'T'>, вам нужно только объявить там и создать геттер.

    private static ArrayList<String> bandsArrayList;

    public ArrayList<String> getBandsArrayList() {
        if (bandsArrayList == null) {
            bandsArrayList = new ArrayList<>();

            String[] bands = {"Metallica", "Iron Maiden", "Nirvana"};
            bandsArrayList.addAll(Arrays.asList(bands));
        }
        return bandsArrayList;
    }

Инициализирует переменную и использует метод [addAll (Collection collection)](http://developer.android.com/intl/pt-br/reference/java/util/ArrayList.html#addAll(java.util.Collection))

1 голос
/ 10 июля 2011

Используя отладчик, я определил, что Array.asList (title) возвращает «Arrays $ ArrayList» (т. Е. Внутренний класс класса Arrays), а не java.util.ArrayList.

Это всегдаЛучше всего использовать интерфейс в левой части выражений, в данном случае это List, а не конкретный ArrayList.Это прекрасно работает:

    List<List<String>> stuff = new ArrayList<List<String>>();
    String[] titles = {"ticker", "grade", "score"};
    stuff.add((List<String>) Arrays.asList(titles));
0 голосов
/ 10 июля 2011

Во-первых, Arrays.asList () никогда не следует приводить к ArrayList.Во-вторых, поскольку дженерики были введены в приведение к языку программирования Java, они по-прежнему актуальны при использовании устаревших API пре-дженериков.

В третьих, никогда не используют конкретные классы слева от оператора присваивания.

Итог, скажи

List<List<String>> stuff = new ArrayList<List<String>>();
String line = "a,b,cdef,g";
String delim = ",";
String[] pieces = line.split(delim);
stuff.add(Arrays.asList(pieces));



List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add(Arrays.asList(titles));

и будь счастлив.

...