equals() 메서드의 5대 계약 원칙
2025. 4. 23. 16:49ㆍHigh 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 |