티스토리 뷰

반응형
    public boolean equals(Object obj) {
        return (this == obj);
    }​
    @Test
    void test(){
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("1", 1);
        map1.put("2", 2);

        Map<String, Integer> map2 = new HashMap<>();
        map2.put("1", 1);
        map2.put("2", 2);

        Assertions.assertThat(map1).isEqualTo(map2);
    }

isEqualTo로 HashMap을 비교하면 success가 떨어진다.

왜냐면 isEqualTo는 동등비교이기 때문이다.

 

그런데 내가 만든 TestObject객체로 isEqualTo비교 시 Exception이 발생하였다

@Getter
@AllArgsConstructor
public class TestObject {
    private String first;
}
@Test
void test2(){
    TestObject testObject = new TestObject("1");
    TestObject testObject2 = new TestObject("1");

    Assertions.assertThat(testObject).isEqualTo(testObject2);
}

 

아니 똑같은 동등비교인데 (new 연산자로 생성되는(주소값이 다른))

왜 TestObject는 안되는걸까 의문이 생겼다.

 

궁금하기에 isEqualTo를 까보면 아래와같다.

isEqualTo를 타고 들어가다보면

 

StandardComparisonStrategy 의 areEqual로 객체를 비교하는데 해당 내용을 보니

@Override
  public boolean areEqual(Object actual, Object other) {
    if (actual == null) return other == null;
		// 생략 //
    return actual.equals(other);
  }

이렇게 actual.equals로 비교를 하는것이다.

 

Map같은 경우 equals로 값을 꺼내서 비교하는 코드가 선언되어있다.

public boolean equals(Object o) {
    if (o == this)
        return true;

    if (!(o instanceof Map))
        return false;
    Map<?,?> m = (Map<?,?>) o;
    if (m.size() != size())
        return false;

    try {
        for (Entry<K, V> e : entrySet()) {
            K key = e.getKey();
            V value = e.getValue();
            if (value == null) {
                if (!(m.get(key) == null && m.containsKey(key)))
                    return false;
            } else {
                if (!value.equals(m.get(key)))
                    return false;
            }
        }
    } catch (ClassCastException unused) {
        return false;
    } catch (NullPointerException unused) {
        return false;
    }

    return true;
}

 

하지만 TestObject의 경우 equals 메소드를 선언하지 않았기에 

가장 최상단에 있는 Object의 equals를 비교하게된다.

    public boolean equals(Object obj) {
        return (this == obj);
    }

 

그렇기에 TestObject가 같지 않다고 Exception이 발생하는 것이다.

 

해결방법은 간단하다.

 

@EqualsAndHashCode를 추가하여 동등비교 자동생성 메서드를 만들어주는것이다.

@Getter
@AllArgsConstructor
@EqualsAndHashCode // 추가
public class TestObject {
    private String first;
}

 

 

반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함