equals() 메서드의 5대 계약 원칙

2025. 4. 23. 16:49High Level Programming Language/Learning the Java Language

자바에서 equals() 메서드를 오버라이딩할 때 반드시 따라야 하는 "5대 계약 원칙(5 contracts of equals method)"객체의 논리적 동등성을 안정적으로 비교하기 위한 필수 조건들입니다. 이 계약들은 자바 API 문서(java.lang.Object.equals)에 명시되어 있으며, 컬렉션이나 정렬, 캐시, ORM 등 다양한 컴포넌트에서 올바른 동작을 보장하기 위해 절대 위반해서는 안 되는 규칙들입니다.

 

📌 equals() 메서드의 5대 계약 원칙

1. 반사성 (Reflexivity)

어떤 객체 x에 대해, x.equals(x)는 항상 true여야 합니다.

  • 자신과의 비교는 항상 참이어야 하며, 이는 기본적인 자기동일성 원칙입니다.
  • 위반하면 자료구조에서 무한 루프가 발생할 수도 있음.
Person p = new Person("John", 30);
assert p.equals(p); // ✅ 항상 true

 

2. 대칭성 (Symmetry)

x.equals(y)true이면, y.equals(x)도 반드시 true여야 합니다.

  • 서로에 대한 동등성의 판단이 한쪽만 true이면 절대 안 됨.
  • 예를 들어 equals() 안에서 instanceof 사용 시, 대칭성 위반이 자주 발생할 수 있음.
@Override
public boolean equals(Object obj) {
    if (obj instanceof Person other) {
        return this.name.equals(other.name); // ⚠️ 문제될 수 있음
    }
    return false;
}
  • 위처럼 작성된 경우, Employee extends Person이라면,
    • person.equals(employee)는 true일 수 있지만
    • employee.equals(person)는 false가 될 수 있습니다 (대칭성 위반 ❌)

 

3. 추이성 (Transitivity)

x.equals(y)이고 y.equals(z)이면, x.equals(z)도 반드시 true여야 합니다.

  • 이 규칙은 객체들 간의 비교 연쇄관계를 위해 중요합니다.
  • 추이성 위반은 Set에서 동등 객체를 여러 번 저장하게 만들 수 있음.
Person p1 = new Person("Kim", 30);
Person p2 = new SubPerson("Kim", 30);
Person p3 = new SubPerson("Kim", 30);

p1.equals(p2); // true
p2.equals(p3); // true
p1.equals(p3); // ❌ false (추이성 위반)

 

4. 일관성 (Consistency)

x.equals(y)의 결과는, 객체 상태가 변하지 않는 한, 여러 번 호출해도 항상 동일해야 합니다.

  • equals의 결과는 상태 불변(immutable)을 전제로 동일해야 합니다.
  • 단, 객체의 필드 값이 바뀌면 equals의 결과도 바뀔 수는 있습니다.
Person p1 = new Person("Kim", 30);
Person p2 = new Person("Kim", 30);

for (int i = 0; i < 10; i++) {
    assert p1.equals(p2); // ✅ 항상 true (일관성 유지)
}

 

5. null 비교에 대한 비허용성 (Non-nullity)

어떤 객체 x에 대해, x.equals(null)은 항상 false여야 합니다.

  • equals는 null과 비교 시 절대로 예외를 발생시키면 안 되며, 무조건 false를 반환해야 합니다.
Person p = new Person("Kim", 30);
assert !p.equals(null); // ✅ 항상 false
  • null-safe equals 구현 예:
    @Override
    public boolean equals(Object obj) {
      if (obj == null) return false;
      // ...
    }

 

📌 equals() 계약 위반 시 발생 가능한 심각한 문제들

위반한 계약 발생 가능한 문제
대칭성 HashSet.contains()가 오작동
추이성 TreeSet, SortedSet에서 정렬/중복 제거 오류
일관성 Map.get(), Set.remove() 실패
null 비교 NullPointerException 발생

 

✅ 결론

equals()는 단순한 메서드가 아니라, 수학적 이항 관계를 강제하는 함수형 계약입니다. 이 5대 계약을 위반하면, 객체 기반 자료구조가 신뢰성을 잃게 되고, 프로그램 전체에 잠복성 버그가 발생할 수 있습니다.

'High Level Programming Language > Learning the Java Language' 카테고리의 다른 글

Prime Number 17  (1) 2025.04.23
Prime Number 31  (0) 2025.04.23
Object.equals()  (0) 2025.04.23
POJO vs JavaBean  (0) 2025.04.23
JavaBean의 Property란?  (0) 2025.04.23