조건문 파트에서 잠시 다뤘던
==(동등 비교 연산자)와 equals() 메소드의 차이를 자세히 알아보자.
먼저 데이터 타입과 메모리에 대한 이해가 필요하다.
원시 데이터 타입과 클래스
원시 데이터 타입(primitive)
- 자바에서 기본적으로 다루는 데이터 타입
- boolean, byte, char, short, int, long, float, double 총 8개가 있다.
- 원시 데이터 타입의 변수는 선언되면 메모리(Stack)에 공간이 할당되고, 실제 값이 들어간다.
👉 원시 데이터의 경우, ==연산자는 변수가 가리키는 값을 토대로 비교한다.
String같은 기본이 아닌 데이터 타입(non primitive)
- java.lang.Object 클래스를 비롯해 여기에서 파생된 다른 모든 클래스들을 포함한다.
- 클래스는 new 키워드를 통해 인스턴스가 만들어지는 시점에 또 다른 메모리 구역(Heap)에서 새로운 공간을 할당하여 값을 저장하고, 변수는 그 값이 저장된 메모리의 주소를 가리키게 된다.
👉 인스턴스 간 ==연산자를 이용할 경우, 그 메모리의 주소를 비교한다.
String 변수 생성 시 주소 할당
String 변수를 생성하는 방법은 2가지다.
- new 키워드를 이용한 방식
- 리터럴을 이용한 방식
String 변수는 기본이 아닌 데이터 타입(non primitive)이지만 리터럴을 이용한 방식은 조금 다르다.
문자열 리터럴로 문자열을 생성할 때, 이미 같은 문자열을 생성한 적이 있다면 새로 메모리 공간을 할당하지 않고, 새로운 변수는 기존의 문자열이 저장된 메모리(String pool(Heap))의 주소를 가리키게 된다.
👉 이러한 경우에 ==연산자를 이용하면 같은 주소를 가리키고 있기 때문에 true가 나오게 된다.
== vs equals
public class EqualsApp {
public static void main(String[] args) {
// == vs equals
int a = 1;
int b = 1;
System.out.println(a == b); // true
// new 키워드를 이용한 방식
String s1 = new String("JAVA");
String s2 = new String("JAVA");
System.out.println(s1 == s2); // false
// 리터럴을 이용한 방식
String s3 = "JAVA";
String s4 = "JAVA";
System.out.println(s3 == s4); // true
System.out.println(s1.equals(s4)); // true
}
}
위의 코드에서 변수와 메모리의 관계를 그림으로 나타내보자.
== 연산자는 변수가 일차적으로 가리키고 있는 메모리 공간의 값을 기준으로 판단한다.
s1, s2, s3(s4) 변수는 각각 10번지, 11번지, 12번지라는 주소 값을 가리키고 있기 때문에 ==연산자를 이용하면 false라고 연산하게 된다.
반면, equals 메소드는 구현에 따라 다르지만, 변수가 최종적으로 가리키고 있는 값을 기준으로 판단한다.
고로 다른 번지에 저장되어 있는 s1, s2, s3(s4) 변수에 대해서도 같다고 판단하게 된다.
결론
내가 주소 값이 아닌 데이터 값(내용)이 같은지 비교하고 싶다!
👉 원시 데이터 타입이면? ==(동등 비교 연산자) 사용
👉 원시 데이터 타입이 아닌 타입이면? equals 메소드 사용
※ 이 글은 생활코딩 JAVA - 제어문 강의를 듣고 정리한 내용입니다.
'🌎 Web > Java' 카테고리의 다른 글
[Java] 정수 나눗셈 연산, 증감 연산자, while문과 조건식 (0) | 2022.11.18 |
---|---|
[Java] 논리 연산자 (0) | 2022.03.16 |
[Java] 조건문(Conditional Statement) (0) | 2022.03.11 |
[Java] Boolean 데이터 타입 (0) | 2022.03.11 |
[Java] 제어문(Java Flow Control) (0) | 2022.03.11 |