Перейти к основному содержимому

Необработанные типы в Java

· 3 мин. чтения

1. Введение

В этом кратком руководстве мы рассмотрим необработанные типы, что они собой представляют и почему их следует избегать.

2. Необработанные типы

Необработанный тип — это имя универсального интерфейса или класса без аргумента типа:

List list = new ArrayList(); // raw type

Вместо:

List<Integer> listIntgrs = new ArrayList<>(); // parameterized type

List<Integer> — это параметризованный тип интерфейса List<E> , а Listнеобработанный тип интерфейса List<E> .

Необработанные типы могут быть полезны при взаимодействии с неуниверсальным унаследованным кодом.

В противном случае, однако, это обескуражен. Это потому что:

  1. Они не выразительны
  2. Им не хватает безопасности типов, и
  3. Проблемы наблюдаются во время выполнения, а не во время компиляции

3. Невыразительный

Необработанный тип не документирует и не объясняет себя так, как это делает параметризованный тип.

Мы можем легко сделать вывод, что параметризованный тип List<String> — это список, содержащий String s. Однако необработанному типу не хватает этой ясности, что затрудняет работу с ним и с его методами 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) возвращает строку с индексом позиции в параметризованном типе List<String> .

Однако для необработанного типа List он возвращает Object . Таким образом, нам необходимо приложить дополнительные усилия, чтобы проверить и определить тип элемента в необработанном списке типов и добавить соответствующее приведение типов. Это может привести к ошибкам во время выполнения, поскольку необработанный тип небезопасен .

4. Небезопасный тип

Мы получаем поведение до дженериков с необработанными типами. Таким образом, список необработанного типа принимает Object и может содержать элемент любого типа данных . Это может привести к проблемам безопасности типов, когда мы смешиваем параметризованные и необработанные типы.

Давайте посмотрим на это, создав некоторый код, который создает экземпляр List<String> перед передачей его методу, который принимает необработанный тип 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<String> , который был передан в качестве аргумента, теперь содержит String и Integer .

Компилятор выводит предупреждение из-за использования необработанных типов:

Note: RawTypeDemo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

5. Проблемы во время выполнения

Отсутствие безопасности типов в необработанном типе имеет причинный эффект, который может привести к исключениям во время выполнения.

Давайте изменим предыдущий пример, чтобы метод A получал элемент в позиции индекса 1 нашего List<String> после вызова метода 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) возвращает Integer , который нельзя присвоить переменной типа String :

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

6. Заключение

С необработанными типами сложно работать, и они могут привести к ошибкам в нашем коде.

Их использование может привести к катастрофическим последствиям, и, к сожалению, большинство таких аварий происходит во время выполнения.

Ознакомьтесь со всеми фрагментами этого руководства на GitHub .