Подтвердить что ты не робот

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

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

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

Ответ 5

Используя отладчик, я определил, что Array.asList(titles) возвращает "ArrayLay 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));

Ответ 6

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

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

Ответ 7

Во-первых, Arrays.asList() никогда не следует бросать в ArrayList. Во-вторых, поскольку generics были введены в 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));

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