equals()와 "==" 뭐가 다르지?

Sandro·2022년 11월 24일
0

java

목록 보기
1/3
post-thumbnail

요약

  • == : 변수의 을 비교하는 연산자.
  • equals()
    • 오버라이드 하지 않은 equals()는 ==와 동일하다.
    • 원하는 대로 오버라이드해서 사용하자.

== ?

카드 종류와 숫자를 변수로 가진 카드 클래스가 있다.

class Card {
    private String kind;
    private int number;
}

같은 값을 가지는 객체를 2개 생성하고 비교연산자 ==로 두 객체가 같은지 확인한다.

public static void main(String[] args) {
    Card card1 = new Card("spade", 1);
    Card card2 = new Card("spade", 1);

    System.out.println(card1 == card2);  // false
}

false가 출력된다.

왜 같지 않을까?

먼저 기본형 변수와 참조형 변수의 차이를 알아야 한다.

기본형 타입 변수인 기본형 변수는 메모리에 실제 값을 저장한다.

// 기본형 타입
// boolean, char, byte, short, int, long, float, double - 8개
int i = 1;
boolean bool = true;

기본형 타입을 제외한 모든 타입의 변수인 참조형 변수는 메모리에 인스턴스의 주소를 값으로 갖는다.

// 참조형 타입
String str = "문자열";
Scanner sc = new Scanner(System.in);

변수 card1card2Card 타입의 참조형 변수다.

따라서 변수의 값을 비교하는 == 연산자는 두 변수가 가지고 있는 인스턴스의 주소를 비교한다.

두 인스턴스는 같은 값("spade", 1)을 가졌지만 하나의 인스턴스가 아니라 메모리에 독립적으로 자리한 인스턴스다.

System.out.println(System.identityHashCode(card1)); // 883049899
System.out.println(System.identityHashCode(card2)); // 2093176254
// 인스턴스 주소로 생성된 해시코드. 인스턴스의 주소가 같다면 같은 해시코드가 반환된다.

따라서 == 비교 연산자로는 두 객체가 논리적으로 같은지 확인할 수 없다.

논리적으로 같다?

"두 객체의 id가 같으면 같은 객체다." , "두 객체의 일련번호가 같으면 같은 객체다."

와 같이 물리적으로 같은 객체는 아니지만 조건이 만족한다면 같은 객체로 취급한다.

그러면 어떻게 두 객체가 논리적으로 같은지 알 수 있을까?

equals()

Object 클래스에 정의된 equals를 사용하면 된다. 하지만 equals를 사용해도 false가 나온다.

System.out.println(card1.equals(card2));  // false

그 이유는 Object 클래스에 정의된 equals 메서드를 확인해보면 알 수 있다.

public boolean equals(Object obj) {
    return (this == obj);
}
// Object에 정의된 equals 메서드

여기도 == 연산자를 이용해서 인스턴스 주소를 비교하고 있다.

따라서 equals를 오버라이드 해야 한다. 인스턴스 주소를 비교하지 않고 우리가 원하는 조건을 명시한다.

우리가 원하는 결과는 이렇다. “카드의 종류와 숫자가 같으면 같은 카드다.”

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Card card = (Card) o;
    return number == card.number && Objects.equals(kind, card.kind);
}
// equals 오버라이드
System.out.println(card1.equals(card2));  // true
// equals 오버라이드 후 결과 확인

드디어 원하는 결과를 얻었다. :)

profile
안녕하세요!

0개의 댓글