Что произойдёт, если объявить record с полем-массивом и сравнить два таких объекта с одинаковым содержимым массива?
equals вернёт false: сгенерированный equals сравнивает компоненты их собственным equals, а у массива это сравнение по ссылке. hashCode тоже будет по идентичности, toString напечатает адрес.
- Решение: хранить List (List.copyOf) вместо массива
- Или переопределить equals, hashCode, toString через Arrays.equals, Arrays.hashCode
- Массив ещё и изменяем — нужна копия
А ещё IDE и анализаторы предупреждают о массиве в record
Подробно
Это неочевидная ловушка: record выглядит так, будто «всё сделает правильно», но для ссылочных компонентов он вызывает их собственный equals, а у массива это сравнение по идентичности. Заодно и hashCode окажется бесполезным, и toString напечатает адрес вместо содержимого. Правильные решения: хранить неизменяемый List вместо массива — тогда всё работает ожидаемо — либо вручную переопределить equals, hashCode и toString с использованием Arrays. Тот же принцип касается любого компонента с неудачным equals.
Что хотят услышать
- Результат и причина.
- Решения.
Частые ошибки
- Считать, что record корректно сравнит любые компоненты.
- Хранить в record изменяемый массив и полагаться на неизменяемость.
Проверьте себя
Один верный вариант. Подумайте, потом откройте ответ.
Показать варианты и ответ
- ✗equals вернёт true: для массивов компилятор подставляет Arrays.equals
- ✗Компилятор запретит объявлять массив компонентом record
- ✗Будет брошено исключение при сравнении
- ✓equals вернёт false: массивы сравниваются по ссылке
Что спросят дальше
- Почему List предпочтительнее массива в качестве компонента?
- Как сделать компонент-коллекцию по-настоящему неизменяемым?
Разбор темы
- Records: компактные носители данных
Что генерирует record, канонический и компактный конструкторы, ограничения и когда применять.
Связанные вопросы
Разбор собеседования с sotto
После собеседования sotto разбирает разговор: оценка, каждый вопрос — хорошо, частично или слабо, чего не хватило в ответе и над чем поработать к следующему разу. Первые 30 минут бесплатно.