[Java] 문자열 비교 ==와 equals()의 차이

hoonssac·2025년 1월 31일
2

Java

목록 보기
6/8
post-thumbnail

자바로 문제를 풀다가 문자열을 비교해야 하는 상황이 있었습니다.
비교 연산자를 사용해야겠다는 생각에 무의식적으로 ==연산자를 사용하였더니 원하던 결과값을 얻을 수 없었습니다.
그제서야 문자열을 비교하는 상황에서는 equals() 메소드를 사용해야 한다는 걸 떠올렸습니다.

하지만, equals()를 사용해야 한다는 것만 알고 있었지
왜 사용해야 하는 지에 대해서는 모르고 있었습니다.
그래서 자료들을 찾아보았고, 정리를 해보았습니다.

🔎String

먼저, String 변수를 생성하는 과정을 살펴봅시다.
일반적으로 String 변수를 생성하는 방법에는 두 가지가 있습니다.

  1. 리터럴을 이용한 방식
  2. new 연산자를 이용한 방식

리터럴 방식

리터럴 방식으로 String 변수를 생성하는 방법은 다음과 같습니다.

String str = "Chill guy";

이 방식으로 생성된 문자열은 JVMString Pool에 저장됩니다.
그리고 내부적으로 intern() 라는 메서드가 호출됩니다.
주어진 문자열이 String Pool에 존재한다면 그 주소값을 반환하고, 존재하지 않는다면 String Pool에 입력 후 새로운 주소값을 반환합니다.

new 연산자 방식

new 연산자를 사용해 String 변수를 생성하는 방법은 다음과 같습니다.

String str = new String("Chill guy");

이 방식을 통해 문자열을 생성하면, 리터럴 방식과는 다르게 Heap 메모리에 변수가 저장됩니다.

예를 들어 코드를 이렇게 작성했다고 가정해봅시다.

String a = "Chill";
String b = "Chill";
String c = new String("Chill");
String d = new String("Chill");

ab는 리터럴 방식으로,
cd는 new 연산자를 사용하였습니다.

a는 String Pool 영역에 "Chill"이라는 문자열이 존재하지 않기 때문에, 새로 생성이 됩니다.
하지만 b를 선언할 때에는, String Pool에 "Chill"이라는 문자열이 이미 존재하지 때문에 그 주소값을 가지게 됩니다.
ab는 같은 주소값을 갖게 되는 것이죠.

그리고 cd는 new 연산자 방식으로 생성했기 때문에, Heap 영역 안에서 서로 독립적인 주소값을 가지게 됩니다.
그림으로 표현하면 아래와 같습니다.

🔎비교 방식

앞서 살펴보았듯이, 문자열 변수의 생성 방식에 따라 서로 같은 주소값을 가지는 경우와 다른 주소값을 가지는 경우가 존재합니다.
위의 그림에서 데이터 값은 a, b, c, d 모두 "Chill"로 같을 수 있지만, 주소값을 비교해본다면 ab는 같은 주소값, cd는 다른 주소값을 가지고 있다는 것을 알 수 있었습니다.

다시 처음으로 돌아와서, 우리는 주소값보다는 실제 데이터값을 비교하는 상황이 많습니다. 그런데, 왜 == 연산자를 사용한 결과와 equals() 메서드를 사용한 결과가 다른 것인지 알아보기 위해 여기까지 왔습니다.
그 차이점은 바로 == 연산자는 주소값을 비교하는 반면,
equals() 메서드는 실제 값을 비교하기 때문입니다.

== 연산자

이 연산자는 비교 대상이 동일한 객체를 참조하는지 여부를 판단하는 연산자입니다. 즉, 객체의 주소값을 비교합니다. 예로 들었던 코드를 ==연산자를 통해 비교해보겠습니다.

String a = "Chill";
String c = new String("Chill");

if (a == c) {
	System.out.println("같음");
}
else {
	System.out.println("다름");
}
다름

a는 Stirng Pool에 저장된 반면, c는 Heap 영역에 저장되어 있기 때문에, 서로 다른 객체를 가리키고 있습니다.
따라서 실제 데이터 값은 같을 지 몰라도, 객체의 주소값을 비교하는 == 연산자는 다르다고 판단하는 것입니다.

equals()

이 메서드는 비교하는 두 대상의 값 자체를 비교하는 메서드입니다. 마찬가지로 예를 들어보겠습니다.

String a = "Chill";
String c = new String("Chill");

if (a.equals(c)) {
	System.out.println("같음");
}
else {
	System.out.println("다름");
}
같음

ac는 서로 주소값이 다르지만, equals() 메서드는 데이터 값을 비교하기 때문에, 변수 생성 방법에 따라 영향을 받지 않는 모습을 볼 수 있습니다.

결론적으로, String 변수를 서로 비교할 때
실제 데이터 값을 비교해야 한다면, equals() 메서드를 사용해야 합니다.

profile
훈싹의 개발여행

0개의 댓글