it-roy-ru.com

приведение Arrays.asList к исключению: Java.util.Arrays $ ArrayList нельзя преобразовать в Java.util.ArrayList

Я новичок в 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.

37
DannyTree

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

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

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

31
Waldheinz

Если вы сделаете это, вы не получите 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.

10
adarshr

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

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

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

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

10
Bohemian

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

List stuff = new ArrayList();
String line = "a,b,cdef,g";
String delim = ",";
stuff.addAll(Arrays.asList(line.split(delim)));
8
Srinivasan.S

Если вы хотите использовать свое свойство как 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
GFPF

Используя отладчик, я определил, что 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));
1
Ant Kutschera

Во-первых, 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));

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

0
AlexR