The major reason is probably that object equality is checked much more often than object identity, so it should be at least as easy.
I haven't seen a definitive statement on this. But there's a pointer in the book Kotlin In Action, by members of the Kotlin team. Section 4.3.1, introducing the ==
operator, first describes Java's comparisons and says that:
in Java, there's the well-known practice of always calling equals
, and there's the well-known problem of forgetting to do so.
In Java, checking object identity is easy:
if (firstObj == secondObj)
But checking object equality is longer and rather less clear:
if (firstObj.equals(secondObj))
— or rather, if you don't want to risk a NullPointerException:
if ((firstObj == null) ? (secondObj == null) : firstObj.equals(secondObj))
You can see how much more of a pain that is to type, and to get right. (Especially when one of those objects is an expression with side-effects…)
So it's easy to forget the difference, or not be bothered, and use ==
instead. (Which is likely to cause bugs that are subtle, hard to spot, and bite intermittently.)
Kotlin, however, makes the most common operation the easier one: its ==
operator checks object equality using equals()
, and takes care of null-checking too. This fixes Java's ‘problem of forgetting to do so’.
(And although interoperability with Java code was clearly a major goal, JetBrains didn't restrict themselves to trying to look like Java; Kotlin borrows from Java where possible, but isn't afraid to change things for the better. You can see that in the use of val
and var
and trailing types for declarations, the different defaults for scoping and openness, the different ways variance is handled, &c.)
One of Kotlin's motivations was to fix many of the problems in Java. (In fact, JetBrains' comparison of the languages starts by listing ‘Some Java issues addressed in Kotlin’.) So it seems likely that this is a major reason behind the change.