스프링 강의를 들으면서, Enum 타입은 비교연산자로 equals()
대신에 ==
를 써도 된다고 배웠는데 이게 무슨 뜻일까.. 싶어서..🤔!
- 자바에서 일반적인 데이터 타입의 비교는
==
이라는 연산자를 사용하여 비교한다.- 그러나 문자열(=String)의 값을 비교할때에는
equals()
라는 메소드를 사용하여 비교한다.
단순히 이렇게만 알고 있었지 왜 인지는 크게 궁금해하지 않았던 것 같다,, 반성하고 있다 하하하하 😂
그래서❗️ 이번 기회에 개념을 확실히 잡고 정리해봐야겠다!
==
연산자는 int,boolean과 같은 primitive type에 대해서는 값을 비교한다. equals()
는 비교하고자 하는 대상의 값 자체를 비교한다.equals()
는 최상위 클래스인 Object에 포함되어 있기 때문에 모든 하위 클래스에서 재정의해서 사용이 가능하다!⬇️ Object클래스의 equals()
의 코드를 살펴보자!
public boolean equals(Object obj) {
return (this == obj);
}
⬇️ 이번에는 String 클래스의 equals()
를 살펴보자!
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;
}
equals()
변수로 들어온 객체가 자신과 주소값이 같다면 true를 리턴한다. equals()
가 문자열을 비교하게 재정의되어 있어서 문자열 비교'도' 가능한 것❗️💡 알고 들어가자 💡
문자열(=String)에 값을 할당하는 방법에는 2가지가 있다!
1️⃣String str = new String("sorzzzzy");
➡️ new 연산자를 이용하는 방식
2️⃣String str = "sorzzzzy";
➡️ 리터럴를 이용한 방식
- 위의 두 가지 방식에는 큰 차이가 존재한다.
리터럴을 사용하게 되면 string constant pool이라는 영역에 존재하게 되고,
new 연산자를 통해 String을 생성하면 Heap 영역에 존재하게 된다.
🤔 : 도대체 그래서 둘의 차이점이 뭐라는 거야 ❓ 코드를 보며 이해해보자 ❗️
public class test1 {
public static void main(String[] args) {
String str1 = "sorzzzzy";
String str2 = new String("sorzzzzy");
if(str1 == str2) {
System.out.println("값이 같습니다");
}else {
System.out.println("값이 다릅니다");
}
}
}
⬆️ 결과는 값이 다릅니다 ❗️
==
연산자는 주소값을 비교한다고 했다!
리터럴을 사용해 string constant pool 영역에 만든 객체와 new 연산자를 통해 heap 영역에 만든 객체는 당연히 주소값이 다를 수 밖에 없다.
public class test2 {
public static void main(String[] args) {
String str1 = "sorzzzzy";
String str2 = new String("sorzzzzy");
if(str1.equals(str2)) {
System.out.println("값이 같습니다");
}else {
System.out.println("값이 다릅니다");
}
}
}
⬆️ 결과는 값이 같습니다 ❗️
equals()
메소드는 주소 값이 아닌 값 자체를 비교하기 때문에 객체가 다르더라도 같은 문자열을 가지고 있다면 같다고 판단한다!
💡 즉,
==
연산자와equals()
의 가장 큰 차이는==
연산자는 비교하고자 하는 대상의 주소값을 비교하는 반면,equals()
는 비교하고자 하는 대상의 값 자체를 비교한다❗️
(equals()
도 내부적으로 주소값을 비교하지만 String클래스에서는equals()
를 재정의해 값을 비교하게 되어있다.)
📌 참고
- 일반적인(int, char 등) 타입들은 Call by Value 형태로 기본적으로 대상에 주소값을 가지지 않는 형태로 사용된다.
- 그러나 String은 일반적인 타입이 아니라 클래스이므로, 기본적으로 Call by Reference 형태로 생성 시 주소값이 함께 부여된다!
- 그렇기에 String 타입을 선언했을 때, 같은 값을 부여하더라도 서로간의 주소값이 다를 수가 있는 것이다 !!