티스토리 뷰

java

동일성과 동등성

주다애 2024. 12. 3. 12:00

🙆‍♂️ 동일성(Identity)

동일성은 두 객체가 메모리 상에서 같은 객체인지 비교하는 개념이다.

 

즉, 동일성두 객체가 메모리에서 동일한 위치를 참조하는지 의미한다.

"==" 연산자를 사용하여 비교한다.

즉, "==" 연산자는 객체의 참조(레퍼런스)를 비교한다. 객체의 값이 같아도 항상 true를 반환하는 것은 아닌 것이다.

대신 기본 타입에 대해서는 "==" 연산자를 사용하면 값을 비교한다.

public static void main(String[] args) {
    Coffee coffee1 = new Coffee(100);
    Coffee coffee2 = new Coffee(100);
    System.out.println(coffee1 == coffee2); // false
}

 

두 Coffee 객체는 같은 값(100)을 가지지만 다른 객체이기 때문에(참조 값이 다르므로) 메모리 상에서 다른 위치를 참조할 것이고 즉 동일성 비교에서는 false가 반환된다.

public static void main(String[] args) {
    Coffee coffee1 = new Coffee(100);
    Coffee coffee2 = new Coffee(100);
    Coffee coffee3 = coffee1;

    System.out.println(coffee1 == coffee3); // true
}

 

위와는 다르게 coffee3 객체는 coffee1과 같은 참조 값를 가진다. 그래서 동일성 비교를 하면 같다고 의미하는 true가 반환된다.

 

🙆‍♀️ 동등성(Equality)

동등성은 객체의 내용(값)을 비교하는 개념이다.

 

즉, 동등성객체의 값이 같은지를 의미한다.

equals() 메소드를 사용하여 비교한다.

두 객체의 값을 equals() 메소드를 사용해 비교했을 때 내용이 같으면 true, 다르면 false를 반환한다.

public static void main(String[] args) {
    Coffee coffee1 = new Coffee(100);
    Coffee coffee2 = new Coffee(100);
    Coffee coffee3 = coffee1;

    System.out.println(coffee1.equals(coffee2)); // false. 왜일까?
}

 

방금 전의 설명과는 다르게 coffee1과 coffee2를 동등 비교 했을 때 false가 나왔다. 두 객체의 내용이 같은데 왜그럴까?

 

문자열(String)이 아닌 다른 객체를 비교할 때 동등 비교를 하려면 equals() 메소드를 오버라이딩 해서 사용해야 한다.

 

위 Coffee 객체의 동등 비교를 하려면 Coffee 클래스에서 equals() 메소드를 오버라이딩해야 한다.

그렇지 않으면 Object 클래스의 equals() 메소드를 사용하기 때문에 비교할 대상이 객체인 경우 객체 주소를 이용해서 비교한다.

즉, 객체를 비교하는 경우 "==" 연산자와 차이가 없다는 것이다.

public class Coffee {
    private int price;

    public Coffee(int price) {
        this.price = price;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        Coffee coffee = (Coffee)o;
        return price == coffee.price;
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(price);
    }
}

 

우리는 객체의 값을 비교하기 위해 equals()메소드를 오버라이딩했다.

(hashCode() 메소드도 함께 오버라이딩 했는데 이건 다음 포스팅에서 알아보겠다😉)

public static void main(String[] args) {
    Coffee coffee1 = new Coffee(100);
    Coffee coffee2 = new Coffee(100);
    Coffee coffee3 = coffee1;

    System.out.println(coffee1.equals(coffee2)); // true
}

 

그럼 이렇게 true가 반환된다! 우리가 원하는대로 객체의 값을 비교하는 동등 비교를 한 것이다.

 

📜 문자열(String)의 객체 비교

문자열(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() 비교를 하면 동등 비교가 되는 것이다.

 

또한 String은 객체인데 "==" 비교를 했을 때 두 값이 같으면 true를 반환한다.

public static void main(String[] args) {
    String str1 = "Hello World!";
    String str2 = "Hello World!";
    System.out.println(str1 == str2); // true
}

 

그 이유는 문자열 리터럴문자열 상수 풀(String Constant Pool)에서 관리된다. 그래서 동일한 리터럴은 재사용된다.

즉 동일한 문자열 리터럴에 대해서 "==" 비교를 하면 같다고 판단하고 true를 반환하는 것이다.

 

그런데 new 키워드를 사용해서 문자열을 생성하면 매번 다른 객체를 생성한다. 그래서 같은 문자열이라도 서로 다른 객체가 된다.

public static void main(String[] args) {
    String str1 = "Hello World!";
    String str2 = "Hello World!";
    String str3 = new String("Hello World!");
    String str4 = new String("Hello World!");

    System.out.println(str1 == str3); // false
    System.out.println(str4 == str3); // false
}

 

그래서 str3과 str4는 서로 다른 객체이므로 "==" 비교를 하면 false가 반환되는 것이다.

 

즉, 우리는 문자열 비교를 할 때 항상 equals() 메소드를 사용하는 것이 동등성 비교를 위해 좋은 선택이다.

'java' 카테고리의 다른 글

얕은 복사와 깊은 복사  (0) 2024.11.27
일급 컬렉션  (0) 2024.11.23
자바의 Checked Exception VS Unchecked Exception  (1) 2024.11.21
인터페이스 vs 추상클래스  (0) 2024.05.16
상속과 메모리 구조  (0) 2023.12.21
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
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
글 보관함