Сегодня я столкнулся с чем-то очень простым, но чрезвычайно сбивающим с толку. Мне нужно было преобразовать список в массив. Список содержит экземпляры String
. Прекрасный пример использования List.toArray(T[])
, поскольку мне нужен экземпляр String[]
. Однако это не сработало бы, если бы явное выражение результата не было String[]
.
В качестве тестового сценария я использовал следующий код:
import java.util.Arrays;
import java.util.List;
public class MainClass {
public static void main(String args[]) {
List l = Arrays.asList("a", "b", "c");
String stuff[] = l.toArray(new String[0]);
System.err.println(Arrays.asList(stuff));
}
}
который не компилируется. Это почти точная копия примера в javadoc, но компилятор говорит следующее:
MainClass.java:7: incompatible types
found : java.lang.Object[]
required: java.lang.String[]
String stuff[] = l.toArray(new String[0]);
^
Если я добавлю актерский состав в String[]
, он будет компилироваться и работать отлично. Но это не то, что я ожидаю, когда смотрю на подпись метода toArray:
<T> T[] toArray(T[] a)
Это говорит мне, что мне не нужно бросать. Что происходит?
Edit:
Любопытно, если я изменил объявление списка на:
List<?> l = Arrays.asList("a", "b", "c");
он также работает. Или List<Object>
. Таким образом, это не должно быть List<String>
, как было предложено. Я начинаю думать, что использование raw List
также влияет на то, как работают общие методы внутри этого класса.
Второе редактирование:
Думаю, я понял это сейчас. То, что Том Хотин написал в комментарии ниже, кажется лучшим объяснением. Если вы используете общий тип необработанным способом, вся информация генерических файлов из этого экземпляра будет удалена компилятором.