Java - строго типизированный язык.Большинство ошибок типа \ all должно быть получено во время компиляции.До Generics вы не можете контролировать, какие типы хранятся в списке.В этом случае (необработанные типы) отложенная проверка типов переходит во время выполнения.Тогда всегда лучше сначала преобразовать любой необработанный тип в конкретный тип, чтобы избежать ошибок во время выполнения.
Но в этом примере мы даже не сможем скомпилировать код, потому что пример показывает, как ненадежные необработанные типы могутбыть, и компилятор понимает это во время компиляции.Я имею в виду эту строку: ((ArrayList)tiles.get(i)).add(j, new Tile());
- это простой случай, который говорит сам за себя.Если мы удалим (ArrayList) и получим (tiles.get(i)).add(j, new Tile());
- , почему компилятор Java должен верить нам , что в (tiles.get(i))
у нас есть List или какой-то объект с add()
методом ?!Да, не должен, и он не делает.
Чтобы проверить, мы можем попытаться скомпилировать простой аналогичный пример с использованием Типы необработанных данных в случае с переменными List:
List listOfLists = new ArrayList();
listOfLists.add(0, new ArrayList());
(listOfLists.get(0)).add("something"); // compile error
Но когда мы говорим компилятору о точном типе внутри listOfLists.get(0)
, и тогда все будет в порядке:
((ArrayList)listOfLists.get(0)).add("something"); // NO compile error
Generics решит эту проблему более точно.Они жестко фиксируют тип для переменных List:
List<List> listOfLists = new ArrayList<List>(); // now List only have List's inside
listOfLists.add(0, new ArrayList());
(listOfLists.get(0)).add("something"); // NO compile error
Компилятор знает, что listOfLists.get(0)
- это список, и у него есть метод add()
.