동일성과 동등성의 차이
자바에서 무언가 같은지 비교할 때 어떻게 했을까 ?==
,equals()
를 이용했다.
🟧 동일성 (identity)
그렇다면 ==
과 equals()
의 차이는 뭘까 ?
둘 다 동일하게 메모리 주소값을 비교하고 있다.
==
, 재정의하지 않은equals
동일성 검사 : 메모리 주소값을 비교한다.
public class Object {
public boolean equals(Object obj) {
// equals는 내부에서 ==를 이용한다.
// 주소가 동일한지 비교한다.
return (this == obj);
}
}
🟧 동등성 (equality)
equals
는 왜 있는걸까 ?
주소값을 비교가 아닌 객체의 값을 비교하고 싶을 때 사용할 수 있다.
(객체의 값이 동일할 경우라면 두 객체가 논리적으로 동일하다고 표현한다.)
두 객체가 논리적으로 같은 것을 표현하고 싶다면 equals
를 재정의하면 된다.
이렇게 논리적으로 같은지 판단하는 행위를 동등성 검사
라고 한다.
논리적으로 같은지 비교하도록 재정의된
equals
동등성 검사 : 논리적으로 같은지 비교한다.
아래는 논리적으로 같은 객체에 대해서 equals
를 재정의 했을 때와 하지 않았을 경우의 예시이다.
🟢 case01. equals를 재정의하지 않은 경우
두 객체 이름01, 이름02는 논리적으로 동일하다.
하지만 equals를 재정의하지 않아서 주소값을 비교하고 있다.
@DisplayName("equals를 재정의하지 않으면 주소값을 비교한다.")
@Test
void equals() {
// 이름01과 이름02의 각 객체의 값은 hyena로 논리적으로 같다.
final Name 이름01 = new Name("hyena");
final Name 이름02 = new Name("hyena");
// equals를 재정의하지 않았다.
// 주소값으로 비교하 때문에 다르다.
assertThat(이름01).isNotEqualTo(이름02); // 테스트 PASS
}
class Name {
private final String value;
public Name(final String value) {
this.value = value;
}
}
🟢 case02. equals를 재정의한 경우
두 객체 이름01, 이름02는 논리적으로 동일하다.
equals를 재정의해서 객체의 값을 비교하고 있다.
@DisplayName("equals를 재정의해서 객체의 값을 비교한다.")
@Test
void equals() {
// 이름01과 이름02의 각 객체의 값은 hyena로 논리적으로 동일하다.
final Name 이름01 = new Name("hyena");
final Name 이름02 = new Name("hyena");
// equals를 재정의해서 객체의 값을 비교한다.
// 객체의 값을 비교하기 때문에 같다.
assertThat(이름01).isEqualTo(이름02); // 테스트 PASS
}
class Name {
private final String value;
public Name(final String value) {
this.value = value;
}
// IntelliJ equals 기본 재정의
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final Name name = (Name) o;
return Objects.equals(value, name.value);
}
}
'💬 언어' 카테고리의 다른 글
[JVM] Java Virtual Machine Architecture (0) | 2023.07.02 |
---|---|
equals 와 hashcode 를 함께 정의해야 하는 이유는? (0) | 2023.03.20 |