본문 바로가기
Java

[Java] 문자열 비교와 문자열 풀(String Pool)

by 작은돼지 2022. 7. 31.

new로 생성된 객체는 리터럴과 달리 heap 영역 내의 서로 다른 메모리를 할당받기 때문에 서로 다른 객체로 간주된다.

이는 문자열 비교 시에 equals를 사용해야 하는 이유와도 관련이 있다.


String str1 = "Hello";
String str2 = new String("Hello");

System.out.println(str1 == str2); // false
System.out.println(str1.equals(str2)); // true

str1은 문자열 리터럴을 참조하고 있고

str2는 new 키워드를 사용하여 새로운 String 객체를 생성한 것이다.

 

링크

https://www.digitalocean.com/community/tutorials/what-is-java-string-pool

 

문자열 리터럴의 경우 Heap 영역 내의 'String Pool'이라는 특수한 메모리 공간에 위치한다.

문자열 풀 내에 "Hello"라는 문자열이 있는 지 확인하고

없다면 새로운 객체를 생성하고, 존재한다면 그 객체를 참조하게 된다.

 

반면에 new 키워드를 사용하면 매번 새로운 객체가 생성되므로

두 변수는 서로 다른 참조값을 가지게 된다.

 

동등 연산자(==)는 피연산자가 가지고 있는 참조값을 비교하기 때문에 참조 대상의 문자열이 무엇인지는 상관이 없다.

결과적으로 참조변수 str1, str2은 서로 다른 참조값을 가지고 있는 상태이기 때문에 false가 반환된다.

 

그렇다면 거꾸로 new 키워드로 먼저 String 객체를 생성한 후에 문자열 리터럴 "Hello"를 생성한다면 어떨까?


String str1 = new String("Hello");
String str2 = "Hello";

System.out.println(str1 == str2); // false

 

str2의 "Hello" 문자열 리터럴은 컴파일 시점에 문자열 풀에 저장되며, 클래스 로딩 시에 해당 문자열을 참조한다.

명시적으로 new를 사용하여 런타임 시점에 생성된 String 객체는 이 문자열 풀과는 별도로 생성된 것이므로 여전히 false가 반환된다.