ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 9/12 TIL | 연휴 끝. 동등성 이해하기!
    📝 기록/매일의 기록 2022. 9. 12. 20:17

    그렇게 다시 시작된 4주차 학습엔 드디어 TDD가 등장하였는데 정말이지 혼란스러웠다. 아샬님이 강의에서 테스트 케이스를 짜는 그 순간의 맥락들이 나에게는 바로 와닿지 않았기 때문이다. 약간 "아 이게? 지금? 이렇게까지?" 이런 마음들의 연속.

    그래도 3주 정도 했다고 이또한 꾸준히 반복해서 인출하고, 아샬님의 흐름을 계속 복기하다 보면 금방 따라갈 수 있을 거란 확신이 생겼다. 모쪼록 파이팅해야겠다는 다짐과 함께 오늘의 TIL은 이번 주 배운 키워드 중 "동등성"에 대해서 한번 정리해보려고 한다.


    '동등성'은 항상 '동일성'이 따라온다. 그럼 대체 그 둘의 차이는 무엇일까?

    먼저, 동일성은 말 그대로 '동일하다'는 뜻으로, 두 개의 객체가 완전히 같은 경우를 의미한다. 완전히 같다는 건 두 객체가 사실상 하나의 객체로 봐도 무방하다는 건데 즉, 메모리의 주소 값이 같기 때문에 두 변수가 같은 객체를 가리킨다는 것이다.

    🔼 refVar2와 refVar3는 같은 주소값을 가지고 있어 동일하다.

    두 객체가 동일한지는 == 연산자를 통해 판별할 수 있다. 참고로 Primitive Type은 객체가 아니라 주소가 없으므로 == 연산자를 사용하였을 때 내용이 같으면 동일하다고 판단한다.

    동등성은 역시나 말 그대로 '동등하다'는 뜻으로, 두 개의 객체가 같은 정보를 갖고 있는 경우를 의미한다. 동등성은 변수가 참조하고 있는 객체의 주소가 서로 다르더라도 내용만 같으면 두 변수는 동등하다고 판별한다. 참고로 동일하면 동등하지만, 동등하다고 동일한 것은 아니다.

    String str1 = new String("aaa");
    String str2 = new String("aaa");
    
    System.out.println(str1 == str2); // false
    System.out.println(str1.equals(str2)); // true

    위 코드의 경우 new 키워드를 통해 다른 String 객체를 메모리에 할당하였으므로 str1과 str2가 가리키는 객체의 주소 값은 다르다. 그렇기에 동일하지 않다. 반면, String이 재정의한 equals() 연산자에 의해 두 객체의 내용이 같으므로 동등하다고 할 수 있다.

    // String 클래스에서 재정의한 equals() 메서드
    
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        return (anObject instanceof String aString)
                && (!COMPACT_STRINGS || this.coder == aString.coder)
                && StringLatin1.equals(value, aString.value);
    }

    사실 String에서 재정의한 equals()만을 사용해왔기에 이번 주 강의에서 동등성을 비교하기 위해 equals() 메서드를 오버라이딩하는 것을 첨엔 이해하지 못했다(원래 그렇게 비교해주는 놈이 아니었어..? 하는 마음에..). 먼저 오버라이딩이란, 상속받은 부모 클래스의 메서드를 자식 클래스에서 재정의하여 사용하는 것을 말한다. 기본적으로 Object 클래스에서 정의하는 equals() 메서드는 동일성을 비교하고 있기 때문에 동등성을 판단하려면 자식 객체에서 오버라이딩 작업이 필요하다.

    // Object 클래스에 정의되어 있는 equals() 메서드
    
    public boolean equals(Object obj) {
        return (this == obj);
    }
    // 필요에 의해 내가 오버라이딩한 equals() 메서드
    
    @Override
    public boolean equals(Object other) {
        TransactionResult otherTransactionResult = (TransactionResult) other;
    
        return this.transaction == otherTransactionResult.transaction
                && this.amount == otherTransactionResult.amount;
    }

    위와 같이 실제로 Object 클래스와 String 클래스에서 구현해놓은 메서드를 비교해보고, 내가 오버라이딩한 메서드를 같이 확인해봄으로써 equals()를 좀 더 자세히 이해할 수 있었다! 👍🏻