Если вы собираетесь обрабатывать исходный код вашей программы с помощью Java SE 5.0 или более поздних версий, то можете при создании списочных массивов указывать тип элементов, которые могут хранить в нем. Однако в ряде случаев приходится обеспечивать совместимость с уже существующим кодом, в котором использованы сырые списочные массивы, реализуемые с помощью класса ArrayList.
Предположим, что в программе присутствует следующий код:
1 2 3 4 5 |
public class EmployeDB { public void update(ArrayList list) { ... } public ArrayList find(String query) { ... } } |
Вы можете указать в качестве параметра метода update() типизированный списочный массив безо всякого приведения:
1 2 |
ArrayList<Employee> staff = ...; employeeDB.update(staff); |
Объект staff просто передается методу update.
Несмотря на то что компилятор не считает данное выражение ошибкой и даже не выводит предупреждающее сообщение, такой подход нельзя считать полностью безопасным.
Метод update() может добавлять в списочный массив элементы, типы которых отличаются от Employee. Это звучит пугающее, но если подумать, именно такое поведение характерно для версий, предшествовавших Java SE 5.0. Целостность виртуальной машины Java должна быть обеспечена в первую очередь, потому что, хотя уровень безопасности и не снижается, воспользоваться преимуществом проверки типов на этапе компиляции не удается.
Если же вы попытаетесь использовать обычный сырой списочный массив вместо типизированного, компилятор отобразит предупреждающее сообщение:
1 2 3 |
// При обработке следующей строки будет выведено // предупреждающее сообщение ArrayList<Employee> result = employeeDB.find(query); |
Чтобы увидеть текст предупреждающего сообщения, надо указать при вызове компилятора опцию -Xlint:uncheked.
Попытка выполнить приведение типов не исправит ситуацию:
1 2 |
// На этот раз появится другое предупреждающее сообщение ArrayList<Employee> result = (ArrayList<Employee>) employeeDB.find(query); |
Изменится лишь сообщение. На этот раз оно информирует о несогласованном приведении типов.
Данная ситуация возникает из-за некоторых ограничений обобщенных типов языка Java. Для совместимости компилятор после проверки соблюдения правил работы с типами преобразует типизированные списочные массивы в обычные объекты ArrayList. В процессе выполнения программы все списочные массивы одинаковы. Виртуальная машина не получает информацию о типах. Поэтому приведения типов (ArrayList) и (ArrayList<Employee>) при работе программы обрабатываются одинаково.
В таких условиях от ваших действий мало что зависит. Модифицируя имеющейся код, вам остается следить за сообщениями компилятора и успокаивать себя тем, что они не свидетельствуют о наличии серьезных ошибок.