String: 문자열이 자주 변경되지 않는 경우나 리터럴 문자열을 재사용해야 할 때 적합합니다. 불변성으로 인해 안전하며, 문자열을 자주 수정하지 않을 때 적합합니다.StringBuffer: 멀티스레드 환경에서 문자열을 빈번하게 수정해야 할 때 사용합니다. 문자열 수정 시 동기화가 필요할 때 유용합니다.StringBuilder: 단일 스레드 환경에서 문자열을 자주 수정해야 할 경우, 성능이 가장 좋습니다. 동기화가 필요 없는 상황에서 StringBuffer보다 빠릅니다.| 특성 | String | StringBuffer | StringBuilder |
|---|---|---|---|
| 불변성 | 불변(Immutable) | 가변(Mutable) | 가변(Mutable) |
| 스레드 안전성 | 스레드 안전 | 스레드 안전 (동기화) | 스레드 안전하지 않음 |
| 성능 | 연산이 적을 때 좋음 | StringBuilder보다 느림 | 단일 스레드에서 가장 빠름 |
| 메모리 사용 | 매 연산마다 새 객체 생성 | 가변 크기의 버퍼 사용 | 가변 크기의 버퍼 사용 |
| 사용 시나리오 | 문자열 변경이 적은 경우 | 멀티스레드 환경, 문자열 변경이 많은 경우 | 단일 스레드, 문자열 변경이 많은 경우 |
| 주요 메서드 | concat(), substring(), charAt() | append(), insert(), delete(), reverse() | append(), insert(), delete(), reverse() |
| 동기화 | 해당 없음 | 메서드 레벨 동기화 | 동기화 없음 |
| 용량 변경 | 해당 없음 | 자동 (명시적으로도 가능) | 자동 (명시적으로도 가능) |
| toString() | 자기 자신 반환 | 현재 버퍼의 내용을 String으로 반환 | 현재 버퍼의 내용을 String으로 반환 |
// String
String str = "Hello";
str = str + " World"; // 새로운 String 객체 생성
// StringBuffer
StringBuffer sbuf = new StringBuffer("Hello");
sbuf.append(" World"); // 기존 객체 수정
// StringBuilder
StringBuilder sbld = new StringBuilder("Hello");
sbld.append(" World"); // 기존 객체 수정
연산 횟수가 증가할수록 StringBuilder와 StringBuffer의 성능 차이가 String에 비해 크게 벌어집니다.