동일성(Identity)
두 객체가 완전히 같은 경우를 칭한다. 완전히 같다는 의미는 메모리에 저장된 객체 중 같은 객체를 가리킨다는 의미다. 즉, 각 변수에 저장된 객체의 주소가 같은지를 비교한다.
위 그림에서 refVar2, refVar3 둘 다 객체2를 가리키고 있기 때문에 두 변수가 가리키는 객체는 동일하다고 말할 수 있다.
두 객체가 동일한지는 ==연산자를 통해 판별한다.
참고로 int, double 같은 Primitive 타입은 객체를 갖지 않기 때문에 == 연산자를 사용했을 때 값이 같으면 true 값이 리턴된다.
동등성(Equality)
동등성은 두 객체에 저장된 값이 같은 값인 경우를 의미한다. 동등성은 변수가 참조하고 있는 객체의 주소가 서로 다르더라도 내용만 같으면 두 변수는 동등하다고 이야기한다.
💡동일하면 동등하지만, 동등하다고 동일한 것은 아니다.
동일성 동등성 코드
String str1 = new String("aaa");
String str2 = new String("aaa");
System.out.println(str1 == str2);
System.out.println(str1.equals(str2));
new 키워드를 통해 다른 String객체를 메모리에 할당하였으므로 str1과 str2가 가리키는 객체의 주소 값은 다르므로 동일하지 않다.
하지만 String이 재정의한 equals() 연산자에 의해 두 객체의 내용이 같으므로 동등하다고 할 수 있다.
false
true
Equals 함수
모든 클래스의 부모 클래스인 Object에서의 equals 함수 구현 코드다.
public boolean equals(Object obj) {
return (this == obj);
}
단순히 == 연산자로 바로 동일성을 비교하고 있다. 해당 메소드를 오버라이드 하지 않는 이상 equals함수는 ==연산자와 다르지 않다.
Equals함수 오버라이드
String
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
String 클래스에서는 == 연산자로 동일성을 판단하고 그렇지 않으면 String클래스의 인스턴스인지 판단한 후 문자 하나하나가 같은지 비교한다. 모든 문자가 같을 때 동등하다고 판단한다.
Integer
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
Integer클래스에서는 Integer클래스의 인자인지 확인한 후 값이 같은지 확인한다. 이 때 동등하다고 판단한다.
정리
동일성과 동등성의 차이는 무엇인가?
두 객체가 할당된 메모리 주소가 같으면 동일하고, 두 객체의 내용이 같으면 동등하다고 말한다. 동일성은 == 연산자를 통해 판별할 수 있고, 동등성은 equals연산자를 통해 판별할 수 있다.
== 연산자와 equals 연산자의 차이는 무엇인가?
== 연산자는 객체의 동일성을 판별하기 위해 사용하며, equals연산자는 두 객체의 동등성을 판별하기 위해 사용한다.
equals 연산자는 재정의하지 않으면 내부적으로 == 연산자와 같은 로직을 수행하므로 차이가 없다. 따라서 equals 연산자는 각 객체의 특성에 맞게 재정의를 해야 동등성의 기능을 수행한다.
'IT' 카테고리의 다른 글
퍼사드 패턴(Facade Pattern) (0) | 2022.11.10 |
---|---|
접근 제어자 (0) | 2022.11.09 |
스프링부트에서 Redis 사용해보기 (0) | 2022.11.09 |
동시성 문제(synchronized, pessimistic lock, optimistic lock) (0) | 2022.11.07 |
스프링 batch + scheduler 정산 시스템 구현 (0) | 2022.11.03 |