Back-End/Java

String, StringBuilder, StringBuffer 의 차이점

김검정 2023. 10. 26. 12:22

자바에서는 대표적으로 문자열을 처리하는 클래스로 String, StringBuilder, StringBuffer 라는 3가지 클래스를 제공한다.

3가지로 구분되는 이유는 무엇이며 무엇이 다른지 정리해보자.

 

가장 먼저 String 과 다른 클래스의 차이점은 String 은 immutable(불변), 다른 두 클래스는 mutable(가변)의 차이점이다.

 

String 자료형만으로도 + 연산이나 concat() 메소드로 문자열을 이어붙일 수 있다. 하지만 덧셈(+) 연산자를 이용해

String 인스턴스의 문자열을 결합하면, 내용이 합쳐진 새로운 String 인스턴스를 생성하게 되어 문자열을 많이 결합하면 할수록

공간의 낭비가 생기고 속도 또한 매우 느려지게 된다. 왜냐하면 초기 공간과 다른 값에 대한 연산에서 많은 시간과 자원을 사용하게 되기

때문이다.

 

String 으로 할당했을때 메모리 사용을 살펴보자

 

 

그래서 자바에서는 이러한 문자열 연산의 낭비를 막기 위해 문자열 전용 자료형을 제공해주는데 StringBuffer 이다.

StringBuffer 클래스는 내부적으로 Buffer 라고 하는 독립적인 공간을 가지게 되어, 문자열을 바로 추가할 수 있어 공간의

낭비도 없으며 문자열 연산 속도도 매우 빠르다는 특징이 있다.

 

StringBuffer sb = new StringBuffer(); // StringBuffer 객체 생성

sb.append("Hello");
sb.append(" "):
sb.append("Java");
String result = sb.toString();

System.out.println(result); // Hello Java

StringBuilder는 StringBuffer와 거의 비슷한 자료형인데 둘의 차이점은 

StringBuffer 는 멀티 스레드 환경에서 안전하다는 장점이 있고, StringBuilder 는 문자열 파싱 성능이 가장 우수하다는 장점이 있다.

 

정리하자면 

  • String은 짧은 문자열을 더할 경우 사용한다.
  • StringBuffer는 스레드에 안전한 프로그램을 개발할때, 개발 중인 시스템이 스레드에 안전한지 모를 경우 사용한다.
  • StringBuilder 는 스레드의 안전 여부가 상관 없는 프로그램을 개발할 때 사용하면 좋다.

 

StringBuffer 의 버퍼(데이터 공간)의 크기의 기본값은 16개의 문자열을 저장할 수 있는 크기이며, 생성자를 통해 그 크기를 

별도로 설정할 수도 있다. 

만약 문자열 연산중 할당된 버퍼의 크기를 넘겨도 상관없다. 자동으로 버퍼를 증가시켜 주기 때문이다.

 

메서드 설명
StringBuffer() 버퍼의 길이를 지정하지 않으면 크기가 16인 버퍼를 생성한다.
StringBuffer(int length) length 길이를 가진 StringBuffer 클래스의 인스턴스(buffer)를 생성
StringBuffer(String str) 지정한 문자열 (str)의 길이보다 16 만큼 더 큰 버퍼를 생성
StringBuffer append() 매개변수로 입력된 값을 문자열로 변환하여 StringBuffer 인스턴스가 저장하고 있는 
문자열의 뒤에 덧붙임
int capacity() StringBuffer 인스턴스의 버퍼크기 반환
int length() StringBuffer 인스턴스에 저장된 문자열의 길이 반환
char charAt(int index) 지정된 위치(index) 에 있는 문자를 반환
StringBuffer delete(int short, int end) 시작위치(start) 부터 끝 위치(end) 사이에 있는 문자를 제거, 단 end 위치의 문자는 제외
StringBuffer deleteCharAt(int index) 지정된 위치(index)의 문자를 제거
StringBuffer insert(int pos, boolean b)
StringBuffer insert(int pos, String str) 

등등
두 번째 매개변수로 받은 값을 문자열로 변황하여 지정된 위치(pos)에 추가 
StringBuffer replace(int start, int end, String str) 지정된 범위 (start ~ end) 의 문자들을 주어진 문자열로 변경
String toString() StringBuffer 인스턴스의 문자열을 String 으로 변환
void setLength(int newLength) 지정된 길이로 문자열의 길이를 변경 
길이를 늘리는 경우에는 나머지 빈공간들을 널문자(\u000)로 채운다.
String subString(int start) 지정된 밤위 내의 문자열을 String 으로 뽑아서 반환

StringBuffer 클래스의 메서드와 StringBuilder 클래스 메서드 사용법은 동일하다.

 

StringBuffer / StringBuilder 의 메모리공간을 살펴보자

따라서 값이 변경될 때마다 새롭게 객체를 만드는 String 보다는 문자열의 추가,수정,삭제가 빈번하게 발생한다면

StringBuffer / StringBuilder 를 사용하는것이 좋다.

 

간단하지만 이해하기 쉬운 예제로 for문을 돌면서 *을 추가하는 예제를 들 수 있다.

String str = "*";

for (int i = 1; i < 10; i++) {
	str += "*";
}
StringBuffer sb = new StringBuffer("*");

for(int i = 1; i < 10; i++) {
	sb.append("*");
}

String 객체일 경우 매번 * 문자열이 업데이트 될때마다 계속해서 메모리 블럭이 추가되게 되고, 일회용으로 사용된 이 매모리들은 후에 

Garbage Collector (GC)의 제거 대상이 되어 빈번하게 Minor GC를 일으켜 Full GC(Major GC)를 일으킬 수 있는 원인이 된다.