Обложка канала

Библиотека Java разработчика

9291 @BookJava

Библиотека Java разработчика. Книги по программированию на Java.

Библиотека Java разработчика

4 года назад
Открыть в
Что такое heap pollution? Как было сказано ранее, массивы в Java ковариантны. А значит, можно обратиться к объекту типа String[] через переменную типа Object[], и положить туда например Integer. Такой код скомпилируется, но в момент записи произойдет ArrayStoreException. Дженерики защищены инвариантностью. Если попытаться положить List<Object> в List<String>, эта же по сути ошибка произойдет уже на этапе компиляции. Heap pollution – ситуация, когда эта защита не срабатывает, и переменная параметризованного типа хранит в себе объект, параметризованный другим типом. Простейший пример: List<String> strings = (List) new ArrayList<Integer>(); Документация гарантирует, что при компиляции всего кода целиком, heap pollution не может возникнуть без варнинга этапа компиляции. Heap pollution может произойти в двух случаях: при использовании массивов дженериков и при смешивании параметризованных и raw-типов. Raw types – это параметризованные типы без указания параметра. Пример с raw types, приводящий к heap pollution, уже был описан выше: List<String> strings = (List) new ArrayList<Integer>(); Использовать raw types не надо вообще, причины подробно изложены в главе 26 Effective Java. Если информация о дженериках не нужна, используется символ wildcard (<?>). Компилятор не даст создать массив параметризованного типа, это приведет к ошибке generic array creation. Картинка ниже иллюстрирует, к чему это могло бы привести. Параметризованный тип varargs-аргумента метода вызывает ту же проблему, т.к. varargs – не что иное как параметр-массив. Вот почему он так же приводит к предупреждению компилятора «possible heap pollution». Если вы уверены что риска нет, с Java 7 это предупреждение заглушается аннотацией @SafeVarargs.