본문 바로가기

개발/Java

[Java] StringBuilder vs StringBuffer


String

C언어에서 문자열은 char형 배열로 표현하지만 자바는 문자열을 위한 String 클래스를 제공하며 java.lang 패키지에 포함되어 있다.

 

immutable class

String 클래스에는 문자열을 저장하기 위해 문자형 배열 참조변수(char[]) value를 인스턴스 변수로 정의해놓고 있다. 한번 생성된 String 인스턴스는 문자열을 읽어 올 수만 있고 변경은 불가능하다. 

 

아래와 같은 코드를 실행하면 인스턴스내의 문자열이 바뀌는것이 아니라 새로운 문자열이 담긴 String 인스턴스가 생성된다.

String a = "a";
String b = "b";
a = a + b;

 

 

'+' 연산자를 사용해서 문자열을 결합하게 되면 매 연산마다 새로운 문자열을 가진 String 인스턴스가 생성된다. 이는 메모리 공간 차지와 성능저하로 이어지게 된다. 하여 String 보다는 StringBuffer 클래스 또는 StringBuilder 클래스를 사용하는 것이 좋다.


StringBuffer

StringBuffer 클래스의 인스턴스를 생성할 때 char 배열이 생성되고, 이 배열은 문자열을 저장 및 편집하기 위한 Buffer로 사용된다.

 

mutable class

StringBuffer는 스레드 세이프하며 변경가능하다. StringBuffer인스턴스 생성자는 4가지가 있다.

StringBuffer 생성자 / 출처 : 공식 Doc

1. StringBuffer() 

버퍼의 크기를 지정해주지 않으면 16개의 문자를 저장할 수 있는 크기의 버퍼를 생성한다.

StringBuffer sb = new StringBuffer();
System.out.println(sb.capacity()); //16

2. StringBuffer(CharSequence seq)

seq 길이 + 16 만큼의 버퍼 크기를 생성한다.

StringBuffer sb = new StringBuffer();
sb.append("test");
StringBuffer sb1 = new StringBuffer(sb);
System.out.println(sb1.capacity()); //20

3. StringBuffer(int capacity)

capacity 만큼의 버퍼 크기를 생성한다.

StringBuffer sb = new StringBuffer(200);
System.out.println(sb.capacity()); //200

4. StringBuffer(String str)

str 길이 + 16 만큼의 버퍼 크기를 생성한다.

StringBuffer sb = new StringBuffer("test");
System.out.println(sb.capacity()); //20

 

작업하려는 문자열의 길이가 버퍼의 크기보다 크다면 내부적으로 버퍼의 크기를 증가시키는 작업이 수행된다.

이때 배열의 길이는 변경될 수 없으므로 새로운 길이의 배열을 생성한 후 이전 배열의 값을 복사해야하고, 길이가 증가된 새로운 배열을 참조하게 된다.

 

StringBuffer 변경

String 과 달리 StringBuffer는 변경 가능하다.

StringBuffer sb = new StringBuffer("aaa");
sb.append("zzz");
System.out.println(sb); //aaazzz

위 코드를 그림으로 나타내면 아래와 같다.

 

String 과 달리 기존 인스턴스에 String이 추가된다.

append()

append()는 StringBuffer, 자신의 주소를 반환한다. 

 

StringBuffer sb = new StringBuffer("aaa");
sb.append("zzz");
StringBuffer sb2 = sb.append("11");
System.out.println(sb); //aaazzz11
System.out.println(sb2); //aaazzz11

위 코드를 그림으로 나타내면 아래와 같다.

sb에 새로운 문자열 "11"이 추가되고 sb자신의 주소를 반환하여 sb2dpsms sb의 주소인 0x100이 저장된다.

sb와 sb2가 모두 같은 StringBuffer 인스턴스를 가리키고 있으므로 같은 내용이 출력된다.


StringBuilder

StringBuilder는 StringBuffer에서 스레드의 동기화만 뺀 인스턴스이다.

이 부분을 제외하곤 완전히 똑같은 기능으로 작성되어 있기때문에 프래그램의 환경을 고려하여 선택하면 된다. 


즉 다시 정리해보자면 아래와 같다.

  String StringBuffer StringBuilder
Storage String Pool Heap Heap
Modifiable No (Immutable) Yes (Mutable) Yes (Mutable)
Thread Safe Yes Yes No
Synchronized Yes Yes No

참고 문서 : Java의 정석(남궁성 지음), java 공식 Doc

'개발 > Java' 카테고리의 다른 글

[Java] Java OOP(Object-Oriented Programming) 란  (0) 2021.08.03
[Java] Java Object Class  (0) 2021.08.02