Все разделы
Выбрать школу

Школа. Увлечения. Большое будущее.

PROSCHOOLS · ОБРАЗОВАНИЕ РЯДОМ

Ваш город

Выберите город, чтобы находить образование и возможности рядом.

Как учитываем городКаталог и кнопки «Выбрать школу» покажут школы выбранного города.Онлайн-курсы, учебник, ГДЗ и задания к экзаменам доступны по всей России.

Популярные города

Будет выбран: Вся Россия

Учебные материалы останутся прежними.

Поиск по сайту

По всему сайтуШколы выбранного города — выше в результатах

С чего начнём?

↑ ↓ — выбрать результат · Enter — открыть · Esc — закрыть

Raw types в Java: почему List без параметра опасен

💻 Информатика · 10 класс

Чем raw type отличается от diamond и List<Object>, как unchecked предупреждения превращаются в ошибки выполнения.

Клавиатура в компьютерном классе
Иллюстрация к предмету «Информатика»Hmartil · Wikimedia Commons · CC BY-SA 4.0

Что называется raw type

Raw type — использование имени обобщённого класса или интерфейса без аргументов типа. Например, List вместо List<String>. Механизм сохранён для совместимости со старым кодом, созданным до generics. Необобщённый класс сам по себе не является raw type: отсутствие угловых скобок у String не делает его «сырым».

Запись List<String> names = new ArrayList<>(); использует diamond справа, но сохраняет типизацию. Это отличается от List names = new ArrayList();. Пустые угловые скобки при выводе типа не равны полному отказу от параметров.

Как теряется проверка

import java.util.ArrayList;
import java.util.List;

List<String> words = new ArrayList<>();
words.add("cat");
List raw = words;
raw.add(17);              // unchecked warning
String next = words.get(1); // ClassCastException

Фрагмент выполняется внутри метода и намеренно демонстрирует ошибку. Words и raw ссылаются на один список. Через raw добавляется Integer, хотя типизированная ссылка обещает строки. При чтении второго элемента как String возникает ClassCastException.

Предупреждение компилятора — важная часть результата. Если просто отключить отображение unchecked, список не станет безопасным. Проблема не в интерфейсе IDE, а в нарушении обещанного типа содержимого.

Почему List<Object> — другое

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

При этом List<String> нельзя напрямую присвоить List<Object>. Иначе через ссылку Object можно было бы добавить число в список строк. Такое ограничение сохраняет безопасность. Для чтения списка неизвестного типа существует List<?>, но это ещё одна конструкция со своими правилами записи.

Когда встречаются предупреждения

Старый API может возвращать raw List. При присваивании его результата List<String> компилятор не может доказать безопасность всех элементов и выдаёт unchecked conversion. Нужно выяснить контракт API, проверить содержимое и по возможности обновить интерфейс. Одно явное приведение не проверяет автоматически тип каждого элемента коллекции.

Для подробной диагностики используют параметр javac -Xlint:unchecked. Аннотация SuppressWarnings не исправляет данные и должна сопровождать только обоснованную локальную гарантию. Новичку полезнее сначала устранить причину предупреждения.

Разобранный безопасный вариант

Если список должен хранить строки, объявляем обе ссылки с List<String> и добавляем только строки. Попытка add(17) тогда отклоняется при компиляции, до запуска. Если по смыслу нужны разные типы, проектируем List<Object> и явно обрабатываем Object, не обещая String.

Практика

  1. Является ли new ArrayList<>() raw type при типизированном контексте?
  2. В какой момент пример ломается: при add(17) или при чтении как String?
  3. Исправляет ли SuppressWarnings неподходящий Integer?

Ответы

1. Нет: diamond позволяет вывести аргумент типа. 2. Проверяемый сбой происходит при чтении второго элемента как String; добавление через raw сопровождалось предупреждением. 3. Нет: аннотация влияет на диагностику, а не превращает число в строку и не восстанавливает нарушенный контракт.

Связанные материалы

Источники и материалы