Предупреждение компилятора о необработанном типе при вызове Map#put()

Я построил класс Java, который получает универсальные объекты;

Поле только для класса установлено в:

private Map map = new HashMap<T,Integer>();

Моя проблема в том, что во время написания какого-то метода, когда я put метод для объекта HashMap и компилятор предупреждают меня и показывают следующее сообщение:

Тип безопасности: метод put(Object, Object) принадлежит к необработанному типу HashMap. Ссылки на универсальный тип Map<K,V> должен быть параметризован

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

Я буду рад, если вы сможете объяснить мне сообщение и что мне нужно сделать, чтобы устранить его.

Метод, который я написал:

public void addItem(T item) {
    if (this.map.containsKey(item)) {
        this.map.put(item, (int)this.map.get(item) + 1);
    }
    else {
        this.map.put(item, 1);
    }
}

и здесь вы можете увидеть, на что жалуется компилятор:

Скриншот кода

3 ответа

+ Изменить

private Map map = new HashMap();

в

private Map<Type1, Type2> map = new HashMap<>();

где Type1 & Type2 имена классов для карты key & value (соответственно)

Например, чтобы объявить карту String значения, проиндексированные Integers:(обратите внимание, что вы не можете использовать примитивные типы)

private Map<Integer, String> map = new HashMap<>();

Недостаток вашего подхода может быть замечен в строке 3 вашего метода, где необходим понижающий бросок. Очевидно, это может привести к ClassCastException в случае, если пара ключ-значение была заменена другим типом значения. (В этом случае вы понижаете int, что недействительно)

При параметризации карты вы заставляете тип объектов, которые должны содержаться внутри (или тип ключей, которые будут использоваться)

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

Если вы хотите использовать дженерики правильно, недостаточно, если вы используете их только в экземпляре (= создание нового объекта путем вызова new оператор) new HashMap<T,Integer>(), но вы также должны объявить ваши переменные с помощью обобщений:

private Map<T,Integer> map = new HashMap<T,Integer>();

Начиная с Java 7, вам не нужно повторять типы в экземпляре, потому что компилятор достаточно умен, чтобы вывести (= вывести) правильный тип из объявления. Это означает, что вы можете написать только

private Map<T,Integer> map = new HashMap<>();

Конструкция <> называется оператором алмазов в зависимости от его формы.

Ваш компилятор жалуется на использование Map без дженериков, который называется необработанным типом.

Я считаю, что вы не правильно скопировали предупреждение. Мой компилятор говорит

Безопасность типов: метод put(Object, Object) относится к необработанному типу Map.

Обратите внимание на карту, а не на HashMap. Поскольку компилятор не может (как правило) знать, какой фактический экземпляр вы назначили map переменная. Следовательно, компилятор жалуется на необработанный тип переменной map, а не о его фактическом содержании.

И компилятор должен уже жаловаться (если вы как-то его не подавили) на объявление

private Map map = new HashMap<T,Integer>();

Карта является необработанным типом. Ссылки на универсальный тип Map должны быть параметризованы

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

Другие вопросы по тегам