목차
1. String 클래스 구조
2. String 클래스가 불변 객체인 이유
3. StringBuilder
4. StringBuffer
1. String 클래스 구조
- java 17 기준으로 String 클래스 구현 코드를 열어봤다.
- 문자열은 문자 배열 byte[] 로 저장된다.

(안 중요 하니까 참고) java9 부터 내부 구현을 char[] 에서 byte[] 로 저장하도록 바뀌었다고 한다.
- char 타입은 2byte 이다.
- 그런데 보통 문자열로 저장되는 영어와 숫자는 1byte 단위로 메모리를 채운다.
- 문자열이 단순 영어, 숫자로만 표현된 경우, 1byte 단위로 사용하게 된다.
- 그렇지 않은 나머지의 문자의 경우는 2byte 인 UTF-16 인코딩을 사용한다.
-> 1byte 단위로 다루어서 메모리를 더 효율적으로 사용하도록 개선된 것이다.
2. String 클래스가 불변 객체인 이유
- String 의 value는 자바 메모리 영역 중에 Method Area 메서드 영역에 저장된다.
- 메서드 영역 내에 문자열 상수 풀이 있다. String Constant Pool
- 컴파일러는 문자열 리터럴을 컴파일 타임에 미리 최적화 해둔다.
- String Pool에 "hello" 라는 리터럴을 저장해뒀다고 하자. 이 값을 여러 인스턴스들이 같이 참조하고 있다.
- "hello" -> "bye" 로 바뀐다면, 해당 값을 참조하고 있는 다른 인스턴스들도 영향을 받게된다!
- String 클래스가 불변 객체이기 때문에 여러 객체가 동일한 문자열을 공유할 수 있고, 메모리 효율성을 높일 수 있다.
3. StringBuilder
- 문자열 편집이 빈번한 경우, 대부분 StringBuilder 를 쓰게 된다.
- String 은 불변 객체라 값을 자주 바꾸면 너무 많은 인스턴스가 heap 메모리를 차지하게 되버린다.
- 연산 과정에서 쓰인 String 인스턴스는 GC의 대상이 된다.
- 문자열 편집이 끝나면 불변인 String 으로 변환해두자
StringBuilder 사용이 더 나은 경우
- 런타임에 편집 횟수가 정해지는 경우 (몇 만번 ..)
- 조건문을 통해 런타임에 동적으로 문자열을 편집해야 하는 경우
- 매우 긴 문자열을 다룰 때
4. StringBuffer
- StringBuilder 와 StringBuffer 는 똑같은 기능을 제공한다.
- (멀티스레드 관련 내용이라 완전히 이해하지는 못했고 공부중이다.)
- StringBuffer 는 멀티스레드 상황에서 안전하지만, 동기화 오버헤드로 속도가 느리다.
- StringBuilder는 멀티스레드 상황에서 안전하지 않지만, 동기화 오버헤드가 없으므로 비교적 속도가 빠르다.
728x90