data class и object
Знакомимся с классами данных и объектами-одиночками.
data class — особый вид класса для хранения данных, для которого компилятор сам генерирует
equals,hashCode,toStringиcopy.
Очень часто класс нужен лишь для того, чтобы хранить набор полей. Для таких случаев Kotlin предлагает data class — он избавляет от рутины, генерируя полезные методы автоматически.
data class
Достаточно добавить ключевое слово data — и вы получаете осмысленный toString, сравнение по содержимому через == и метод copy.
data class User(val name: String, val age: Int)
fun main() {
val a = User("Аня", 25)
val b = User("Аня", 25)
println(a) // понятный toString
println(a == b) // сравнение по содержимому
}Вывод:
User(name=Аня, age=25) true
Метод copy
copy создаёт копию объекта, позволяя изменить отдельные поля. Это удобно для неизменяемых данных: вместо мутации создаём новый объект.
data class User(val name: String, val age: Int)
fun main() {
val a = User("Аня", 25)
val older = a.copy(age = 26)
println(a)
println(older)
}Вывод:
User(name=Аня, age=25) User(name=Аня, age=26)
object — объект-одиночка
Ключевое слово object создаёт синглтон — единственный экземпляр на всю программу. Удобно для конфигурации или утилит без состояния.
object Config {
val appName = "CodeChick"
fun describe() = "Приложение: $appName"
}
fun main() {
println(Config.describe())
}Вывод:
Приложение: CodeChick
companion object
В Kotlin нет статических членов, как в Java. Их роль играет companion object — объект, привязанный к классу; обращаются к нему через имя класса.
class User(val name: String) {
companion object {
fun guest() = User("Гость")
}
}
fun main() {
val u = User.guest()
println(u.name)
}Вывод:
Гость
Как работает под капотом
Для data class компилятор генерирует equals/hashCode на основе свойств, объявленных в первичном конструкторе (свойства из тела класса в них не участвуют). Поэтому два объекта с одинаковыми полями конструктора равны. object же создаётся лениво при первом обращении и существует в единственном экземпляре — это потокобезопасная реализация паттерна Singleton прямо в языке.
Частые ошибки
- Писать обычный класс там, где нужен
data class. Безdataпридётся вручную писатьequals,toStringиcopy. - Искать
static. Его в Kotlin нет — используйтеcompanion objectили функции верхнего уровня. - Ждать, что поля из тела класса попадут в
equals. Вequalsучаствуют только свойства первичного конструктора.
Итог
data classавтоматически даётequals,hashCode,toStringиcopy.copyсоздаёт изменённую копию объекта.object— синглтон, единственный экземпляр на программу.companion objectзаменяет статические члены Java.