Какой оператор «===» делает в Котлине? Как это работает? Можно ли проверить ссылочное равенство?
val a: Int = 10000 print(a === a) // Prints 'true' val boxedA: Int? = a val anotherBoxedA: Int? = a print(boxedA === anotherBoxedA) // !!!Prints 'false'!!!
но в случае:
var a : Int = 1000 var b : Int = 1000 println(a === b) // print 'true' !!!
val a: Int = 1000
и val b: Int = 1000
не находится в диапазоне -128..127
, но все же ===
истинно или компилятор в некоторых случаях понимает, что его можно принять за одно значение?
Как документировано , оно представляет собой ссылочное равенство :
Ссылочное равенство проверяется операцией === (и ее отрицательной копией! ==). a === b оценивает значение true тогда и только тогда, когда a и b указывают на один и тот же объект.
Ссылочное равенство означает, что две ссылки указывают на один и тот же объект. Например:
fun main(args: Array<String>) { val number1 = Integer(10) // create new instance val number2 = Integer(10) // create new instance val number3 = number1 // check if number1 and number2 are Structural equality println(number1 == number2) // prints true // check if number1 and number2 points to the same object // in other words, checks for Referential equality println(number1 === number2) // prints false // check if number1 and number3 points to the same object println(number1 === number3) // prints true }
Сравните это с кодом Java ниже:
public static void main(String[] args) { Integer number1 = new Integer(10); // create new instance Integer number2 = new Integer(10); // create new instance Integer number3 = number1; // check if number1 and number2 are Structural equality System.out.println(number1.equals(number2)); // prints true // check if number1 and number2 points to the same object // in other words, checks for Referential equality System.out.println(number1 == number2); // prints false // check if number1 and number3 points to the same object System.out.println(number1 == number3); // prints true }
Кроме того, как описано здесь , «бокс чисел не сохраняет идентичность». Итак, boxedA
будет иметь один идентификатор, но у anotherBoxedA
будет другой. Оба имеют структурное равенство, но не ссылочное равенство.
Но почему второй работает? Поскольку тип Kotlin Int
соответствует типу Java int
. Две переменные, сравниваемые во втором примере, являются значениями примитивного типа, а не объектами. Поэтому для них ссылочное равенство точно такое же, как и регулярное равенство.