개발은 아름다워

[ Java ] equals는 왜 쓰는거고 어떻게 쓰는걸까? - 동일성과 동등성 본문

자바

[ Java ] equals는 왜 쓰는거고 어떻게 쓰는걸까? - 동일성과 동등성

do_it_zero 2024. 10. 12. 11:28

Object 클래스가 존재하는 이유는 여러 객체들이 가졌던 공통적인 기능들을 제공하기 위함이다.

Object는 동등성을 비교하기 위한 equals() 를 제공한다.
동등성이란 뭘까??

자바는 두 객체가 같다는 표현을 2가지로 분리해서 제공한다

  • 동일성 : == 연산자를 사용해서 두 객체의 참조가 동일한 객체를 가리키고 있는지 확인
  • 동등성 : equals()메서드를 사용하여 두 객체가 논리적으로 동등한지 확인

“동일”은 완전히 같음을 의미한다. 반면 “동등”은 같은 가치나 수준을 의미하지만 그 형태나 외관 등이 완전히 같지 않는 것을 의미한다.

동일성은 물리적으로 같은 인스턴스인지 참조값을 확인하는 것이고, 동등성은 논리적으로 같은지 확인하는 것이다.
동일성은 메모리의 참조 값이 기준이고 동등성은 사람이 생각하는 논리적인 것이 기준이다.

User a = new User(001); // x001
User b = new User(001); // x002

두 객체의 동일성은 다르다. 왜냐하면 실제 메모리 참조값이 x001과 x002이기 때문이다. 그러나 a나 b의 인스턴스 생성시 초기값이 같으므로 동등하다고 볼 수 있다.

그럼 equals는 뭔뎅?

동일성을 확인할때는 ==을 쓰면 된다.
동등성을 확인할 떄는 equals를 쓰면 된다. 두 인스턴스가 논리적으로 같은지 확인할 떄 쓰면 되는 것이다.

여기서 중요한 것은 동등성이라는 개념은 각각의 클래스마다 다르다는 것이다. 어떤 클래스는 전화번호를 기준으로 동등성을 처리할 수 있고, 어떤 클래스는 회원 번호를 기반으로 동등성을 처리할 수 있다.

그러나 Object 클래스가 제공하는 equqls()는 ==으로 동일성 비교를 제공한다. 따라서 각 클래스에 맞는 동등성 비교를 하기 위해서는 equals()를 오버라이딩하여 각 클래스에 맞게 재정의해야 하는 것이다.

equals 메서드를 구현할 떄 지켜야하는 규칙

  • 반사성 : 객체는 자기 자신과 동등해야함
  • 대칭성 : 두 객체가 서로에 대해 동일하다고 판단하면, 이는 양방향으로 동일해야 한다.
  • 추이성 : 만약 한 객체가 두 번째 객체와 동일하고, 두 번째 객체가 세 번째 객체와 동일하다면, 첫 번째 객체는 세 번째 객체와도 동일해야 한다.
  • 일관성 : 두 객체의 상태가 변경되지 않는 한 equals() 메소드는 항상 동일한 값을 반환해야 한다.
  • null에 대한 비교 : 모든 객체는 null과 비교했을 떄 false를 반환해야한다.

동등성 비교가 항상 필요한 것은 아니다. 동등성 비교가 필요한 경우에만 equals()를 재정의하면 된다. 꼭 필요할 떄만 만들면 되는 것이다. 위와 같은 룰을 지키는 정확한 equals() 구현하기에는 어렵다. 따라서 대부분 IDE에서는 equals() 를 단축키를 이용하여 재정의할 수 있게 되어있다.