[Kotlin] Structual Equality & Referential Eqaulity (Feat. EqualsAndHashCode)

김태훈·2024년 4월 1일
0
post-thumbnail

코틀린의 Eqaulity는 크게 두가지가 존재한다.

  1. Structual Equality : 동등성 (자바의 재정의한 equals)
  2. Referential Equality : 동일성 (자바의 ==)

그렇다면 코틀린과 자바를 비교해보자.

Java와 Kotlin의 차이

JVM에서 100%호환이 가능한 Kotlin은 Java와 어떻게 차이가 있을까?

JAVA

Java에서는 내용을 비교할 때, equals로 객체의 참조 값이 아니라, 내용을 비교할 수 있다는 것을 알고 있다.

사실 엄밀히 말하면 이 말은 틀린 말이다.
Object클래스의 equals는 아래 사진과 같이 정의되어 있다.
즉, 이 말인 즉슨 == 을 통해 객체의 주소값을 비교하고 있다는 뜻이다.

하지만, 우리가 알고있는 대표적인 클래스들은 이러한 equals 메서드를 '주소값'이 동일한 경우뿐만 아니라, '내용'도 동일한지 여부를 확인한다. 이 때문에 우리가, equals 메서드가 내용을 비교하는 메서드라고 착각하기 쉽다. 따라서 equals함수를 재정의했기 때문에 내용을 비교할 수 있다고 바로 알자.

예시 코드

public static void main(String[] args) {
    class Pos{
        int x;
        Pos(int x ){
            this.x = x;
        }
    }
    Pos p1 = new Pos(1);
    Pos p2 = new Pos(1); 
    System.out.println(p1.equals(p2));
    //false
}

위의 예시에서 true로 만들기 위해서는 equals메서드를 재정의 해야한다.

결국 equals 메서드는 객체의 내용(Structual Eqaulity)를 따지기 위해 존재하는 것이고,
== 은 객체의 주소값(Referential Equality)를 따지기 위해 존재한다.

Kotlin

Java의 객체 내용값을 비교하기 위해 재정의한 equals 메서드와 동일한 역할을 Kotlin에서는 ==을 통해 담당한다.

class TestClass(val value: Int) {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is TestClass) return false
        return value == other.value
    }
}

fun test() {
    var a: TestClass = TestClass(10000)
    var b: TestClass? = TestClass(10000)
    println("a === b: ${a === b}") // false
    println("a == b: ${a == b}") // true
}

fun main() {
    test()
}

위 코드의 Byte코드를 통해 Java로 변환하면

public static final void test() {
	TestClass a = new TestClass(10000);
    TestClass b = new TestClass(10000);
    String var2 = "a === b: " + (a == b);
    System.out.println(var2);
    var2 = "a == b: " + Intrinsics.areEqual(a, b);
    System.out.println(var2);
}

처럼 변한다.

이를 통해 Kotlin의 === 은 Java의 ==과 동일하고,
Kotlin의 ==은 Java의 equals 와 동일하다는 것을 알 수 있다.

profile
기록하고, 공유합시다

0개의 댓글