Ответ
Нет, компилятор Java не предупредит об этом. Ответственность за использование иммутабельных (неизменяемых) объектов в качестве ключей HashMap лежит на разработчике.
Почему это важно? Контракт HashMap требует, чтобы хеш-код ключа оставался постоянным на протяжении всего времени его жизни в коллекции. Если ключ-объект изменяется после добавления в мапу, его хеш-код может измениться, и вы не сможете найти или удалить соответствующую запись.
Пример проблемы:
import java.util.HashMap;
import java.util.Map;
class MutableKey {
private String value;
public MutableKey(String value) { this.value = value; }
public void setValue(String value) { this.value = value; }
@Override
public int hashCode() { return value.hashCode(); }
// ... equals() тоже должен быть переопределен
}
public class Main {
public static void main(String[] args) {
Map<MutableKey, String> map = new HashMap<>();
MutableKey key = new MutableKey("A");
map.put(key, "Data");
key.setValue("B"); // Критическое изменение состояния ключа!
System.out.println(map.get(key)); // Выведет: null
// Запись "потерялась", так как HashMap ищет ее по новому хеш-коду.
}
}
Решение: Всегда используйте в качестве ключей иммутабельные типы (String, Integer, LocalDate). Для собственных классов-ключей:
- Объявите класс и все его поля как
final. - Корректно переопределите
equals()иhashCode(), используя только финальные поля. - Не предоставляйте сеттеров, изменяющих состояние.