Почему List <String>.toArray() возвращает Object [], а не String []? как обойти это?
Кто-нибудь знает, почему Java 1.6 имеет такое поведение:
List<String> list = ArrayList<String>();
String[] arr = (String[]) list.toArray();
И я получаю ClassCastException, потому что он возвращает Object [], а не String [].
Я думал
List<T>.toArray()
должен возвращать T [] - нет? Есть ли у кого-нибудь ответ, почему это неудобство существует на этом языке?
А также как обойти это? Как я могу получить String [] из List<String>
без цикла через элементы?
Ответы
Ответ 1
Вам нужно передать массив, поэтому его тип времени выполнения можно использовать как подсказку toArray
. Вместо этого попробуйте toArray(new String[0])
. Вы также можете передать массив предварительно заданных размеров.
Чтобы понять, подумайте, какое стирание стилей нужно будет сделать, чтобы сделать
new T[4]
работа. Если Java допускает, что лучшее, что могло бы сделать после стирания, это
new Object[4]
В большинстве реализаций toArray
используется java.lang.reflect.Array
для построения выходного массива правильного типа с учетом подсказки типа, прошедшего как Class
.
Ответ 2
Поскольку массивы были в Java с самого начала, в то время как generics были введены только в Java 5. И метод List.toArray()
был введен в Java 1.2 до того, как появились дженерики, и поэтому было указано, что он возвращает Object[]
. Многие существующие коды теперь ожидают List.toArray()
для возврата Object[]
, поэтому его нельзя изменить сейчас.
Кроме того, генераторы стираются во время выполнения, поэтому ArrayList
не может даже построить массив соответствующего типа, если он захочет.
Лазейка для этого метода List.toArray(T[])
, который вернет вам массив правильного типа, если вы дадите ему массив правильного типа, чтобы он знал, какой тип использовать.
Ответ 3
Чтобы понять, почему это происходит, просто посмотрите на javadoc для Collection.toArray()
, а затем посмотрите на Collection.toArray(T[] a)
. Также имейте в виду, что дженерики в Java стираются во время выполнения.
Ответ 4
Причины следующие:
-
Метод предшествовал Generics, и они не могли изменить подпись, не нарушая обратной совместимости.
-
В любом случае, поскольку List
построен без Class<T>
, для реализации не существует способа построить массив типа T
.
Ответ 5
Обходной путь будет использоваться:
List<String> list = new ArrayList<>();
list.add("Sputnik");
list.add("Explorer");
//String[] str = list.toArray();
Это обязано бросать: несовместимые типы: Object [] не может быть преобразован в String [] error
Instead use:
String[] str = list.toArray(new String[0]);
or
String[] str = list.toArray(new String[list.size()]);