«1. Введение
В этом кратком руководстве мы рассмотрим необработанные типы, что они собой представляют и почему их следует избегать.
2. Необработанные типы
Необработанный тип — это имя универсального интерфейса или класса без его аргумента типа:
List list = new ArrayList(); // raw type
Вместо:
List<Integer> listIntgrs = new ArrayList<>(); // parameterized type
List\u003cInteger\u003e — параметризованный тип интерфейса List\u003cE\u003e, тогда как List является необработанным типом интерфейса List\u003cE\u003e.
Необработанные типы могут быть полезны при взаимодействии с неуниверсальным унаследованным кодом.
В противном случае, однако, это обескураживает. Это происходит потому, что:
- They are not expressive
- They lack type safety, and
- Problems are observed at run time and not at compile time
3. Невыразительный
Необработанный тип не документирует и не объясняет себя так, как это делает параметризованный тип.
Мы можем легко сделать вывод, что параметризованный тип List\u003cString\u003e — это список, содержащий строки. Однако необработанному типу не хватает этой ясности, что затрудняет работу с ним и с его методами API.
Давайте посмотрим на сигнатуру метода get(int index) в интерфейсе List, чтобы лучше понять это:
/**
* Returns the element at the specified position in this list.
*
* @param index index of the element to return
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException if the index is out of range
* (<tt>index < 0 || index >= size()</tt>)
*/
E get(int index);
Метод get(int index) возвращает строку в позиции index в параметризованном типе List\u003cString\u003e .
Однако для необработанного списка он возвращает объект. Таким образом, нам необходимо приложить дополнительные усилия, чтобы проверить и определить тип элемента в необработанном списке типов и добавить соответствующее приведение типов. Это может привести к ошибкам во время выполнения, поскольку необработанный тип небезопасен.
4. Небезопасность по типам
Мы получаем поведение до дженериков с необработанными типами. Следовательно, список исходного типа принимает объект и может содержать элемент любого типа данных. Это может привести к проблемам безопасности типов, когда мы смешиваем параметризованные и необработанные типы.
Давайте посмотрим на это, создав некоторый код, который создает экземпляр List\u003cString\u003e перед передачей его методу, который принимает необработанный тип List и добавляет к нему Integer:
public void methodA() {
List<String> parameterizedList = new ArrayList<>();
parameterizedList.add("Hello Folks");
methodB(parameterizedList);
}
public void methodB(List rawList) { // raw type!
rawList.add(1);
}
Код компилируется (с предупреждением) , и Integer добавляется в список необработанных типов при выполнении. List\u003cString\u003e, который был передан в качестве аргумента, теперь содержит String и Integer.
Компилятор выводит предупреждение из-за использования необработанных типов:
Note: RawTypeDemo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
5. Проблемы во время выполнения
Отсутствие безопасности типов в необработанном типе имеет причинный эффект, который может привести к исключениям во время выполнения .
Давайте изменим предыдущий пример так, чтобы метод A получал элемент с индексной позицией 1 нашего List\u003cString\u003e после вызова метода B:
public void methodA() {
List<String> parameterizedList = new ArrayList<>();
parameterizedList.add("Hello Folks");
methodB(parameterizedList);
String s = parameterizedList.get(1);
}
public void methodB(List rawList) {
rawList.add(1);
}
Код компилируется (с тем же предупреждением) и генерирует исключение ClassCastException при выполнении . Это происходит потому, что метод get(int index) возвращает целое число, которое нельзя присвоить переменной типа String: код.
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
Их использование может привести к катастрофическим последствиям, и, к сожалению, большинство таких аварий происходит во время выполнения.
Ознакомьтесь со всеми фрагментами этого руководства на GitHub.
«
Check out all the snippets in this tutorial over on GitHub.