본문 바로가기

Language/Java

== vs equals

자바에는 여러가지 데이터 타입이 존재한다. 이 여러가지 데이터 타입을 primitive냐 아니냐의 기준으로 구분할 수 있다.

 

 

자바에서 기본적으로 다루는 데이터 타입은 원시 데이터 타입(primitive data type)이라고 부른다. 원시 데이터 타입의 변수는 선언되면 메모리(Stack)에 공간이 할당되며, 그 메모리 공간 안에 실제 값이 들어가게 된다.

 

int a = 1;
int b = 1;

System.out.println(a == b);		// true
// System.out.println(a.equals(b));	// 원시 데이터 타입은 equals 메소드 사용 불가

 

그래서 위 코드와 같이 원시 데이터의 경우 == 연산자는 변수가 가리키는 값을 토대로 비교하게 된다.

 

반면 java.lang.Object 클래스를 비롯해 여기에서 파생된 다른 모든 클래스들은 원시 데이터 타입이 아니다. 클래스는 new 키워드를 통한 인스턴스가 만들어지는 시점에 또 다른 메모리 구역(Heap)에서 새로운 공간을 할당하여 값을 저장하고 변수는 그 값이 저장된 메모리의 주소를 가리키게 된다. 

 

String s1 = new String("JAVA");
String s2 = new String("JAVA");

System.out.println(s1 == s2);		// false
System.out.println(s1.equals(s2));	// true

 

그래서 위 코드의 경우 인스턴스 간 == 연산자를 이용할 경우 그 메모리의 주소를 비교하게 된다.

 

한편 문자열 리터럴과 같은 방식으로 문자열을 생성한 경우는 위와 같은 방식과는 조금 다르다. 문자열 리터럴로 문자열을 생성할 때, 이미 같은 문자열을 생성한 적이 있다면 새로 메모리 공간을 할당하지 않고, 새로운 변수는 기존의 문자열이 저장된 메모리(String Pool(Heap))의 주소를 가리키게 된다.

 

String s3 = "JAVA";
String s4 = "JAVA";

System.out.println(s3 == s4);		// true
System.out.println(s3.equals(s4));	// true

 

 

그래서 위 코드의 경우에는 == 연산자를 이용하였을 때 같은 주소를 가리키고 있기 때문에 true가 나오게 된다.

 

이런 상황에 대해 변수와 메모리의 관계를 그려보면 다음과 같다.

 

 

== 연산자는 변수가 일차적으로 가리키고 있는 메모리 공간의 값을 기준으로 판단한다. s1, s2, s3(s4) 변수는 일차적으로 각각 10번지, 11번지, 12번지라는 주소를 가리키고 있기 때문에 서로 == 연산자를 이용하면 false라고 연산하게 된다.

 

반면 equals 메소드는 구현에 따라 다르지만, 변수가 최종적으로 가리키고 있는 값으로 판단하여 다른 번지에 저장되어 있는 s1, s2, s3(s4)에 대해서도 서로 같다고 판단하게 된다.

 

다시금 정리하자면 다음과 같다.

 

 

결론적으로, 원시 데이터 타입의 경우 동등 비교 연산자(==)를 사용하고, 원시 데이터 타입이 아닌 경우 equals 메소드를 쓰면 된다.

 

 

 

 

 

[참고자료]

자바 메모리 관리 - 스택 & 힙 https://yaboong.github.io/java/2018/05/26/java-memory-management/

 

자바 메모리 관리 - 스택 & 힙

개요 Java 에서 메모리 관리는 어떻게 이루어지는지 알아보기 위함. Stack 과 Heap 영역 각 역할에 대해 알아본다. 간단한 코드예제와 함께 실제 코드에서 어떻게 Stack 과 Heap 영역이 사용되는지 살펴

yaboong.github.io

Java 자바 - 메모리 사용영역, 참조 타입 변수 특징 https://kephilab.tistory.com/35

 

1. Java 자바 - 메모리 사용영역, 참조 타입 변수 특징

1. 데이터 타입 분류 기본 타입 : 정수, 실수, 문자, 논리 리터럴을 저장하는 타입 (실제 값 저장) 참조 타입 : 객체(Object)의 번지를 참조(저장)하는 타입 (메모리 번지값을 통해 객체를 참조한다.)

kephilab.tistory.com

'Language > Java' 카테고리의 다른 글

접근 제어자 (access level modifiers)  (0) 2022.11.10
main 메소드  (0) 2022.11.10
클래스 (Class)  (0) 2022.11.07
메소드 (Method)  (0) 2022.11.05
상속 (Inheritance)  (0) 2022.11.03