본문 바로가기

Java/Java SE, EE

[Java/Java SE, EE] equals()와 비교 연산자 ==

두 객체를 상호 비교하는 방법으로 equals()와 비교 연산자 ==가 있습니다.

  • equals()
    객체의 값을 비교합니다.
  • 비교 연산자 ==
    객체의 메모리 주소를 비교합니다.

equals()

자바의 모든 클래스는 java.lang.Object를 상속 받습니다. 우리가 작성한 클래스도 명시적으로 extends 키워드를 사용하지 않았더라도 Object 클래스를 상속 받고 있습니다.

  • Object 클래스는 equals() 메소드를 구현합니다.
  • 자바의 모든 객체는 Object 클래스가 구현하는 equals() 메소드를 호출 할 수 있습니다.
  • 일반적으로 equals() 메소드를 오버라이딩하여 사용합니다.

Object 클래스가 구현하고 있는 equals() 메소드는 다음과 같습니다.

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

비교 연산자 ==

객체의 메모리 주소를 비교합니다. 비교 대상이 되는 두 개의 피연산자가 기본 타입(Primitive type) 또는 상수인 경우에도 메모리 주소를 비교합니다. 상수는 상수 풀에서 관리되므로 두 개의 동일한 상수는 동일한 메모리 주소에 저장되어 있습니다.

int a = 10;

System.out.println(a == 10);    // true

테스트

equals()와 비교 연산자 ==를 테스트하기 위해 다음과 같은 Test 클래스를 구현합니다. equals() 메소드를 오버라이딩하고 있으며, 메소드 내부에서는 두 객체의 필드 v의 값을 비교합니다.

public static class Test extends Object {
   public int v;
   
   public Test(int v) {
      this.v = v;
   }
   
   @Override
   public boolean equals(Object obj) {
      if (obj instanceof Test) {
         Test test = (Test) obj;
         if (this.v == test.v) {
            return true;
         }
      }
      
      return false;
   }
}

이어서 Test 객체를 두 개 생성하고, equal()와 비교 연산자 ==를 사용하여 상호 비교합니다.

Test a = new Test(1234);
Test b = new Test(1234);

System.out.println(a == b);
System.out.println(a.equals(b));

코드 실행 결과는 다음과 같습니다.

false
true

비교 연산자 ==는 두 개의 피연산자의 메모리 주소를 비교합니다. 두 객체는 각각 new 키워드를 사용하여 새로 인스턴싱되었으므로 서로 다른 힙 메모리에 저장되어 있습니다. 따라서 결과는 false입니다.

equals()는 Test 클래스에서 오버라이딩하고 있습니다. 오버라이딩 메소드 내부에서는 필드 v를 비교합니다. 두 객체의 필드 v는 1234로 초기화되었으므로 결과는 true입니다.

String 클래스의 equals()

이전 섹션에서 equals() 메소드는 Object 클래스의 것을 오버라이딩하여 사용한다고 설명했습니다. 그렇다면 String 클래스의 equals() 메소드는 어떤 형태를 띄고 있을까요?

public static boolean equals(byte[] value, byte[] other) {
    if (value.length == other.length) {
        int len = value.length >> 1;
        for (int i = 0; i < len; i++) {
            if (getChar(value, i) != getChar(other, i)) {
                return false;
            }
        }
        return true;
    }
    return false;
}

String 클래스는 객체의 값을 비교하기 위해 각 문자열에서 한 글자씩 비교를 수행합니다. 이처럼 자바에서 제공하는 클래스들도 성격에따라 equals() 메소드의 구현 내용에 차이가 있음에 유의해야합니다.