# It seems like there is a wrong explanation about '==' operator on the kotlinlang webpage

**URL:** <https://discuss.kotlinlang.org/t/it-seems-like-there-is-a-wrong-explanation-about-operator-on-the-kotlinlang-webpage/10949>\
**Category:** Language Design\
**Created:** [December 28, 2018, 2:57pm UTC](https://discuss.kotlinlang.org/t/it-seems-like-there-is-a-wrong-explanation-about-operator-on-the-kotlinlang-webpage/10949 "2018-12-28T14:57:42Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![macgebi](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/macgebi/32/5912_2.png) [@macgebi](https://discuss.kotlinlang.org/u/macgebi)\
**Post date:** [December 28, 2018, 2:57pm UTC](https://discuss.kotlinlang.org/t/it-seems-like-there-is-a-wrong-explanation-about-operator-on-the-kotlinlang-webpage/10949/1 "2018-12-28T14:57:42Z")

</div>

[https://kotlinlang.org/docs/reference/operator-overloading.html](https://kotlinlang.org/docs/reference/operator-overloading.html)

> The `==` operation is special: it is translated to a complex expression that screens for `null` 's. `null == null` is always true, and `x == null` for a non-null `x` is always false and won’t invoke `x.equals()` .

This seems wrong with kotlin 1.3 because when x is not null, I can see ‘x == null’ invokes x.equals(null) when I tested it - I used IntelliJ Community Edition with kotlin language version and API version of 1.3.  
And the explanation on the kotlinlang website seems like different from [that on github page](https://github.com/JetBrains/kotlin/blob/native-support/master/spec-docs/operator-conventions.md).  
(I’m not sure which version on github to attach as a link, but I think they’re mostly same.)

> The `==` operation is special in two ways:
> 
> - It is translated to a complex expression that screens for `null` 's, and `null == null` is `true` .
> - It looks up a function with a specific _signature_ , not just a specific _name_ . The function must be declared as
> 
> fun equals(other: Any?): Boolean

---

<div class="post-metadata">

**Author:** ![ilya.gorbunov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ilya.gorbunov/32/1645_2.png) [@ilya.gorbunov](https://discuss.kotlinlang.org/u/ilya.gorbunov)\
**Post date:** [December 29, 2018, 12:59am UTC](https://discuss.kotlinlang.org/t/it-seems-like-there-is-a-wrong-explanation-about-operator-on-the-kotlinlang-webpage/10949/2 "2018-12-29T00:59:25Z")

</div>

Could you show the code where `x == null` invokes `x.equals(null)`?

The following example doesn’t exhibit such behavior:

```run-kotlin

class Foo {
    override fun equals(other: Any?): Boolean {
        println("Foo.equals($other) was called")
        return super.equals(other)
    }
}

fun test(x: Any?) {
    val r1 = x == "string"
    val r2 = x == 1
    val r3 = x == null
}

fun main() {
    test(Foo())
}

```

---

<div class="post-metadata">

**Author:** ![macgebi](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/macgebi/32/5912_2.png) [@macgebi](https://discuss.kotlinlang.org/u/macgebi)\
**Post date:** [December 29, 2018, 2:02am UTC](https://discuss.kotlinlang.org/t/it-seems-like-there-is-a-wrong-explanation-about-operator-on-the-kotlinlang-webpage/10949/3 "2018-12-29T02:02:18Z")

</div>

Thanks for the code.

I think I understood differently from what the document intended. I thought it were a matter of value, not a expression. In my code, I passed null value to a function and used “a == b” expression, not “a == null” expression  
However I still feel this difference can be dangerous even though I don’t know it is intended or not.

```run-kotlin
data class TestClass(val a: Int) {
    override fun equals(other: Any?): Boolean {
        return true
    }
}

fun myEquals(a: Any?, b: Any?): Boolean {
    return a == b
}
fun myEquals2(a: Any?, b: Any?) = a == b

fun main(args: Array<String>) {
    var nonNull = TestClass(7)
    println("equals: ${myEquals(nonNull, null)}")
    println("equals: ${myEquals(null, nonNull)}")
    println("equals: ${myEquals2(nonNull, null)}")
    println("equals: ${myEquals2(null, nonNull)}")
}

```

---

<div class="post-metadata">

**Author:** ![ilya.gorbunov](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/ilya.gorbunov/32/1645_2.png) [@ilya.gorbunov](https://discuss.kotlinlang.org/u/ilya.gorbunov)\
**Post date:** [December 29, 2018, 3:57am UTC](https://discuss.kotlinlang.org/t/it-seems-like-there-is-a-wrong-explanation-about-operator-on-the-kotlinlang-webpage/10949/4 "2018-12-29T03:57:08Z")

</div>

The way how `TestClass` implements `equals` method in this example contradicts the contract of that method: from the principle of symmetry of `equals` for any non-null value `x`, `x.equals(null)` should return `false`.

The Kotlin compiler generates executable code counting on the fact that classes abide the contract when implementing `equals` method and doesn’t try to fix the consequences of violating that contract.

---

<div class="post-metadata">

**Author:** ![macgebi](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/macgebi/32/5912_2.png) [@macgebi](https://discuss.kotlinlang.org/u/macgebi)\
**Post date:** [December 29, 2018, 1:42pm UTC](https://discuss.kotlinlang.org/t/it-seems-like-there-is-a-wrong-explanation-about-operator-on-the-kotlinlang-webpage/10949/5 "2018-12-29T13:42:35Z")

</div>

You’re right. I don’t think my equals is implemented in a right way. I was testing the documented behavior of when equals is called, not behavior of equals itself.  
(I wans’t testing the return value of the ‘==’ statement. Maybe my print statements made you confused.)

My point is “nonNull == null” and “nonNull == b” works differently when b is null.  
I don’t think it matter that equals returns true or not in this issue. Even if I change it to return false which will make it symmetry, the behavior on calling equals is identical.

If you put null for b in the next function, you’ll see it without any statement removed by optimizer in the debugging mode.

```auto
fun testFoo(nonNull: Any?, b: Any?) {
    var k = 3
    if (nonNull == b) {
        k = 10
    }
    if (nonNull == null) {
        k = 10
    }
}

```

----- addition -----  
Or if it’s not a big deal because good ‘equals’ implementations will return false, still I think the documentation can be more accurate. I’m a little bit worried about that the behavior varies by expression or optimizer, not value. To me, that seems requiring too much knowledge for development.
