본문 바로가기

Java

[Java] 동일성과 동등성

동일성 (Identity) : ==

두 객체가 물리적으로 같은지 판단한다.

→ 즉, 같은 인스턴스인지 (메모리 주소가 같은지) 확인한다.

 

기본 데이터 타입은 변수 자체가 값을 직접 저장한다. 즉, 메모리 상에서 실제 값을 저장하고 있다.
따라서 ==을 사용하여도 둘의 값이 같은지를 판단한다.

int a = 1;
int b = 1;

// 값 비교
System.out.println(a == b); // true

 

그러나, 참조 데이터 타입은 변수 자체가 값이 아닌 참조를 저장하여, 값이 같더라도 메모리 주소가 다르다.

따라서 ==을 사용하면 실제로 두 객체가 같은 메모리 주소를 가리키는지 여부를 판단한다.

String str1 = new String("hello");
String str2 = new String("hello");

// '=='는 참조값을 비교 (메모리 주소 비교)
System.out.println(str1 == str2); // false (서로 다른 객체)

 

동등성 (Equality) : equals()

두 객체가 논리적으로 같은지 판단한다.

→ 즉, 내용이나 값이 같은지 비교한다.

 

String str1 = new String("hello");
String str2 = new String("hello");

// '=='는 내용을 비교
System.out.println(str1.equals(str2)); // true

 

그렇다면 아래의 경우는 어떤 결과가 나올까?

public class Person {
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

 

public class Main {
    public static void main(String[] args) {
        Person personA = new Person("Jane", 25);
        Person personB = new Person("Jane", 25);

        System.out.println(personA == personB);       // false (동일성)
        System.out.println(personA.equals(personB));  // false (동등성인데, 재정의 안 했으므로 동일성처럼 작동)
    }
}

 

※ equals()는 Object 클래스의 메서드이다. 모든 객체는 Object 객체의 자손이기 때문에 모든 객체는 equlas()를 사용가능 하다.

 

위의 경우에는 분명 두 객체를 eqauls로 비교하였음에도 false의 결과를 가진다. equals()는 Object의 기본 구현을 따라가고, 이는 == 비교와 같아서 같은 객체(같은 주소)인지를 확인하다. 즉, 동등성 비교를 위해서는 equals를 직접 재정의 해 주어야한다.

 

equals() 의 짝궁 hasCode()

equals()를 재정의한다면 반드시 hashCode()도 함께 재정의해야 한다.
hashCode()는 해시 기반 컬렉션(HashSet, HashMap 등)에서 객체를 비교하거나 저장할 때 내부적으로 함께 사용되기 때문이다.

 

만약 equals()만 재정의하고 hashCode()는 그대로 두면, 두 객체가 논리적으로 같더라도 서로 다른 객체로 판단되어 의도한 대로 동작하지 않을 수 있다.

 

import java.util.Objects;

public class Person {
    String name;
    int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // equals() 재정의
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return age == person.age && Objects.equals(name, person.name);
    }

    // hashCode도 같이 재정의
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}
public class Main {
    public static void main(String[] args) {
        Person personA = new Person("Jane", 25);
        Person personB = new Person("Jane", 25);

        System.out.println(personA.equals(personB));  // true (동등성)
    }
}

'Java' 카테고리의 다른 글

[Java] 쓰레드  (0) 2025.05.01
[Java] 람다 / 스트림  (0) 2025.04.30
[Java] 컬렉션 / 제네릭  (0) 2025.04.30
[Java] 명명 규칙  (0) 2025.04.23
[Java] Enum  (0) 2025.04.21