String, StringBuffer, StringBuilder의 차이에 대해 정리했습니다.
1️⃣ String
개념
- 문자열을 불변(Immutable) 객체로 관리
특징
- 한 번 생성되면 값이 변경되지 않음
- 불변이므로 +, concat() 등으로 수정 시 새 객체를 생성
- 속도 느려짐과 메모리 낭비 가능성 있음
- 문자열 리터럴은 문자열 풀(String Pool)에 저장 → 동일 문자열 재사용
- 스레드 안전(thread-safe) → 불변이라 여러 스레드에서 동시에 사용해도 안전
주요 메소드
length()
: 문자열 길이 반환charAt(int index)
: 특정 위치 문자 반환substring(int begin, int end)
: 부분 문자열 반환toUpperCase()
,toLowerCase()
: 대소문자 변환equals()
,compareTo()
: 문자열 비교trim()
,replace()
,split()
등
사용 예시
1
2
3
String s = "Hello";
s = s + " World"; // 기존 s는 그대로, 새로운 객체 생성
System.out.println(s); // "Hello World"
JAVA에서 String을 불변으로 설정한 이유
캐싱, 보안, 동기화, 성능측면 이점을 얻기 위해
- 캐싱 : String pool에 각 리터럴 문자열의 하나만 저장하며 다시 사용하거나 캐싱에 이용가능하며 이로 인해 힙 공간을 절약할 수 있음
- 보안 : 데이터베이스 사용자 이름, 암호는 수신하기 위해 문자열로 전달되는데, 만일 번지수의 문자열 값이 변경이 가능하다면 해커가 참조 값을 변경하여 보안 문제 발생 가능
- 동기화 : 동시에 실행되는 여러 스레드에서 안정적이게 공유 가능
2️⃣ StringBuffer / StringBuilder
개념
- 문자열을 가변(Mutable) 객체로 관리
특징
- 문자열 수정 가능
- 문자열 변경 시 새로운 객체를 만들지 않고, 독립적인 공간인 버퍼 내부에서 수정
- 공간 낭비 없고, 연산 속도 빠름
- 문자열 조작(추가, 삭제, 변경)이 잦을 때 유리
- 동등 비교 시 String 객체로 변환 후 equals() 사용
차이점
- StringBuffer : 멀티 쓰레드 안전(thread-safe) → synchronized 적용 (성능은 약간 떨어짐)
- StringBuilder : 멀티 쓰레드 안전하지 않음 → synchronized 적용 X (동기화 오버헤드가 없어 성능 빠름)
JAVA에서 synchronized 키워드
여러개의 스레드가 한 개의 자원에 접근할려고 할 때, 현재 데이터를 사용하고 있는 스레드를 제외하고 나머지 스레드들이 데이터에 접근할 수 없도록 막음
web이나 Socket과 같이 비동기 동작 많을 때, StringBuffer 사용하는 것이 안전
주요 메소드
append(String str)
: 문자열 추가 (다양한 자료형 가능 - 문자열로 자동 변환)insert(int offset, String str)
: 특정 위치에 삽입 (두 번째 매개변수의 자료형은 다양함 - 문자열로 자동 변환)delete(int start, int end)
: 부분 삭제deleteCharAt(int index)
: 지정된 위치의 문자 제거replace(int start, int end, String str)
: 부분 교체setCharAt(int index, char ch)
: 지정된 위치의 문자를 두 번째 매개변수로 변경charAt(int index)
: 지정된 위치에 있는 문자 반환substring(int start)
,substring(int start, int end)
: 지정된 범위 문자열 반환reverse()
: 문자열 뒤집기length()
: 문자열 길이 반환setLength(int newLength)
: 지정된 길이로 문자열 길이 변경 (빈공간은 널문자로 채움)capacity()
: 버퍼크기 반환toString()
: StringBuffer를 String으로 변환
사용 예시
1
2
3
4
5
6
7
8
9
10
11
12
StringBuffer sb = new StringBuffer("Hello");
System.out.println(sb);
System.out.println(sb.toString());
System.out.println(sb.substring(2,4));
System.out.println(sb.insert(2,"추가"));
System.out.println(sb.delete(2,4));
System.out.println(sb.append(" World"));
System.out.println(sb.length());
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb); // "Hello World"
3️⃣ 전체 비교 정리
구분 | String | StringBuffer | StringBuilder |
---|---|---|---|
불변성 | 불변 (Immutable) | 가변 (Mutable) | 가변 (Mutable) |
스레드 안전성 | 안전 (불변이라서) | 안전 (synchronized 적용) | 안전하지 않음 |
성능 | 느림 (새 객체 생성) | 빠름 (동기화 때문에 약간 느림) | 가장 빠름 |
사용 시기 | 문자열 변경 거의 없음 | 멀티스레드 환경에서 문자열 조작 | 단일 스레드 환경에서 문자열 조작 |
주요 메소드 | length() , substring() , equals() | append() , insert() , delete() | append() , insert() , delete() |
참고 블로그