String같이 보통의 참조형 변수는 다음과 같이 RAM(힙, 스택)에 저장된다.
변수의 위치(실제 객체의 주소값을 갖는다.) : 스택
실제 객체의 위치 : 힙
하지만 String은 조금 다른 방식으로 저장된다...!
리터럴은 데이터 그 자체를 뜻 한다.
변수에 넣는 변하지 않는 데이터를 의미한다.
Java에서 문자열 리터럴(ex "Hello", "Hi")은 JVM의 Method Area 안의 String Constant Pool에 저장된다.
그래서
String str = "Hello";
에서
str이라는 변수는 스택에 저장되고, "Hello"라는 객체를 String Constant Pool에서 참조한다.
근데
String str2 = new String("Hello");
이 경우
"Hello"는 여전히 String Constant Pool에 저장된다.
하지만 new String("Hello")는 힙에 새로운 String 객체를 생성하고 str2가 그 힙 객체를 참조한다.
| 항목 | String str = "Hello"; | String str = new String("Hello"); |
|---|---|---|
| 저장 위치 | String Constant Pool (메서드 영역) | "Hello"는 Pool에, **실제 객체는 힙(Heap)**에 생성 |
| 객체 생성 수 | 1개 (필요시) | 항상 2개 ("Hello" 리터럴 + new String() 힙 객체) |
| 재사용 여부 | O (리터럴 풀에서 재사용) | X (항상 새 객체 생성) |
| 메모리 효율 | ✅ 좋음 | ❌ 비효율적 |
== 비교 결과 | 동일 리터럴끼리 true | Pool 객체와는 false |
| 추천 여부 | ✅ 일반적으로 권장 | ❌ 특별한 이유 없으면 지양 |
그전에는 String str = new String("Hello");가 좀 더 멋있어서(?) 사용을 많이 했는데, 이제는 String 생성할 때 String str = "Hello"; 방식을 써야겠다.