В чём разница между == и === в Kotlin?
В Kotlin == и === — два разных оператора сравнения, и они имеют разное семантическое значение:
🔹 == — сравнение по значению (equivalent to equals())
-
Это перегружаемый оператор: под капотом вызывает equals() (если он определён).
-
Используется для логического сравнения объектов: содержимое, поля и т.п.
-
Даже если два объекта — разные экземпляры, но у них одинаковые значения, == вернёт true.
Пример:
val a = "hello"
val b = "hello"
println(a == b) // true
Хотя a и b могут быть разными объектами в памяти, их значения равны → equals() возвращает true.
🔸 === — сравнение по ссылке (reference equality)
-
Проверяет, один и тот же ли это объект в памяти.
-
Возвращает true только если переменные ссылаются на один и тот же экземпляр.
Пример:
val a = "hello"
val b = "hello"
println(a === b) // true или false — зависит от интернирования строк
Для строк может быть true из-за кэширования, но:
val x = String(charArrayOf('h','e','l','l','o'))
val y = String(charArrayOf('h','e','l','l','o'))
println(x == y) // true — содержимое одинаковое
println(x === y) // false — разные объекты в памяти
🧠 Таблица различий
Оператор | Что сравнивает | Аналог в Java | Тип сравнения |
---|---|---|---|
\== | Значение (логическое равенство) | a.equals(b) | Переопределяемый |
--- | --- | --- | --- |
\=== | Ссылку (один ли это объект) | a == b (сравнение ссылок) | Непереопределяемый |
--- | --- | --- | --- |
⚠️ Примеры с null
Kotlin обрабатывает null безопасно:
val a: String? = null
val b: String? = null
println(a == b) // true
println(a === b) // true (оба null)
📦 Применимость
-
Используйте ==, если хотите сравнить данные (например, в бизнес-логике).
-
Используйте ===, если важно, один ли это объект в памяти (например, при оптимизациях, работе с синглтонами или кэшами).
✅ Пример различий на практике
data class User(val name: String)
val u1 = User("Alice")
val u2 = User("Alice")
println(u1 == u2) // true — equals() сгенерирован автоматически для data class
println(u1 === u2) // false — это два разных экземпляра
→ Даже если значения одинаковые, объекты разные по ссылке.
Итог
Оператор | Поведение | Когда использовать |
---|---|---|
\== | Сравнивает значения (equals()) | В 99% случаев: сравнение содержимого |
--- | --- | --- |
\=== | Сравнивает ссылки (один объект?) | Когда важно, один ли это экземпляр в памяти |
--- | --- | --- |
Понимание разницы между == и === критично при работе с объектами, особенно в Kotlin, где логика сравнения может быть неочевидной из-за лаконичного синтаксиса.