동일성(identity)
두 개의 객체나 값이이 메모리에서 동일한 위치를 참조하고 있는지를 비교하는 개념입니다.
완전히 같다는 것은, 두 객체를 하나의 객체로 봐도 무방하며, 주소값 또한 같기 때문에 같은 객체를 가리키는 것입니다.
Primitive 타입은 객체가 아니라 주소가 없으므로 == 연산자를 사용했을 때 내용이 같으면 동일하다라고 말할 수 있습니다.
즉, 자바에서 동일성은 == 연산으로 판단합니다.
동등성(Equality)
동등성은 두 개의 객체나 값이 내용적으로 같은지 비교하는 개념입니다.
즉, 변수가 참조하고 있는 객체의 주소가 서로 다르더라도 내용만 같으면 두 변수는 동등하다고 이야기 할 수 있습니다.
만약 동일하면 동등을 만족하지만, 동등하다고 동일한 것은 아닙니다.
해당 변수가 동등한지는 equals() 연산자를 통해 판별할 수 있습니다.
자바에서 동등성은 .equals() 연산으로 판단합니다.
equals()
자바에서 equals() 메서드는 객체의 동등성을 확인하기 위해 사용하는 메서드입니다.
객체의 equals() 메서드를 사용하기 위해선, Object.equals() 메서드를 오버라이딩 하여 해당 클래스의 객체가 동등한지 비교하도록 구현합니다.
equals() 메서드는 객체의 메모리 주소를 비교하는 동일성 과정을 수행할 수도 있기 때문에, 동일하다면 동등하기 때문에 true를 바로 반환합니다.
equals() 를 재정의 할 때 다음 규약을 따라야 합니다.
- 반사성 : null이 아닌 모든 참조 값 x에 대해, x.equals(x)는 true 이다.
- 대칭성 : null이 아닌 모든 참조 값 x,y에 대해 x.equals(y)가 true면 y.equals(x)도 true여야 한다.
- 추이성 : null이 아닌 모든 참조 값 x,y,z에 대해 x.equals(y)가 true 이고, y.equals(z)도 true 이면, x.equals(z)도 true 이다.
- 일관성 : null이 아닌 모든 참조 값 x,y에 대해 x.equals(y)를 반복해서 수행하면 항상 값이 같아야 한다.
- null 아님 : null이 아닌 모든 참조 값 x에 대해 x.equals(null)은 false 이다.
위 내용은 이펙티브 자바에도 포함되어 있습니다.
equals()를 재정의할 때 순서는 다음과 같습니다.
- == 연산자를 통해 자기 참조인지 확인, 즉 동일성을 확인한다.
- instanceof 연산자로 입력이 올바른 타입인지 확인합니다.
- 입력을 올바른 타입으로 형변환 합니다. instanceof 검사를 했기 때문에 오류가 발생하지 않습니다.
- 입력 객체와 자기 자신의 대응되는 핵심 필드들이 모두 일치하는지 하나씩 검사합니다.
주의점
- float과 double을 제외한 기본 타입 필드는 == 연산자로 비교하고, 참조 타입은 각각의 equals() 메서드로, float과 double 필드는 각각의 정적 메서드인 Float.compare(), Double.compare로 비교합니다.
- equals()를 재정의할 땐 hashCode()도 재정의 해야 합니다.
- 왜 hashCode()도 재정의 해야할까요?
'Back-end' 카테고리의 다른 글
왜 float과 double은 == 연산을 사용하면 안될까? (0) | 2023.08.16 |
---|---|
Primitive Type vs Wrapper Class + Wrapper Class 동일성 비교 (0) | 2023.08.16 |
static vs static final vs final In Java (0) | 2023.08.15 |
2023.08.13 TIL (0) | 2023.08.13 |
왜 enum(열거형)을 상속하지 못할까? (0) | 2023.08.13 |