Data-классы
Kotlin data class — это класс, помеченный data, для которого компилятор сам генерирует equals, hashCode, toString, copy и функции componentN. Смысл — избавить вас от рукописного шаблона для «носителей данных» и дать объектам структурное равенство: два экземпляра с одинаковыми полями считаются равными.
Ловушки прячутся в деталях. Генерация охватывает только свойства первичного конструктора — поле, объявленное в теле, не участвует ни в equals, ни в hashCode. А вложенное поле сравнивается по своим правилам: если это обычный (не-data) класс, оно сравнивается по ссылке и рушит равенство всего объекта. Поверх всего лежит контракт «equals согласуется с hashCode», без которого ломается поиск в HashMap и HashSet. Полная карта — в слоях ниже.
Карта темы
- Сгенерированные члены data-класса — что именно генерирует
data class(equals,hashCode,toString,copy,componentN) и почему только свойства первичного конструктора. - Контракт equals ↔ hashCode — правило согласованности
equalsиhashCodeи что ломается вHashMap/HashSetпри его нарушении.
Частые ошибки и ловушки
| Ошибка | Последствие |
|---|---|
Думать, что в equals входят свойства из тела класса | Поле вроде val id = ... в теле молча исключается из равенства |
Считать, что вложенное не-data поле сравнится по значению | Обычный класс сравнивается по ссылке — объект перестаёт быть равен своей копии |
Переопределить equals, забыв про hashCode | Равные объекты дают разный хэш и теряются как ключи в HashMap/HashSet |
| Класть в data-класс изменяемое поле-ключ | Мутация после вставки меняет hashCode, и ключ «пропадает» из map |
Полагать, что copy копирует поля из тела | copy принимает параметры только для свойств первичного конструктора |
Значение для собеседований
Data-классы спрашивают, чтобы проверить, понимаете ли вы, что автогенерация — не магия «всё равно всему», а строго определённый набор членов из строго определённого набора свойств. Кандидат, который сразу называет «только первичный конструктор» и «equals обязан согласоваться с hashCode», выглядит сильнее того, кто говорит «data class сам всё сравнивает».
Что обычно проверяют:
- Что именно генерирует
data classи из каких свойств. - Почему поле из тела класса не влияет на равенство и
copy. - Контракт
equals/hashCodeи почему его нарушение ломаетHashMap. - Как ведёт себя вложенное не-
dataполе внутри data-класса.
Типичный неверный ответ: «data class сравнивает все поля объекта по значению». На деле в equals/hashCode входят только свойства первичного конструктора, а вложенное поле сравнивается по правилам своего типа — обычный класс по ссылке, поэтому два «одинаковых» объекта легко оказываются неравны.