본문 바로가기

BE/JAVA

[JAVA] StringBuffer, StringBuilder 클래스 정리

목차
1. StringBuilder, StringBuffer 사용하는 이유 
2. StringBuilder
3. StringBuffer
4. 공통/차이점 

 

📌 1. StringBuilder, StringBuffer 사용하는 이유 

기존 String 클래스 한계

String클래스는 한번 생성되면 문자열이 변경되지 않으므로 불변(immutable)한 성질을 가지고 있습니다.

따라서 기존 문자열에 새로운 문자열을 추가하고자 하는 경우

메모리에서 문자열이 추가되는 것이 아니라, 새로운 메모리가 할당되어 문자열이 생성됩니다.

따라서 문자열의 변경이 빈번한 경우 StringBuilder와 StringBuffer클래스를 활용해야 합니다. 

 

아래와 같이 String sb = "testStr";로 선언하고 sb = sb.concat("12"); 를 수행한 경우 sb 문자열은 새 주소가 할당됩니다. 

 

문자열을 변경할 때마다 새로운 메모리가 할당되는 것은 자원낭비가 일어나기 때문에

StringBuilder와 StringBuffer클래스를 활용해야 합니다.

 

 

📌2. StringBuilder 

StringBuilder클래스는 문자열을 변경하거나 이어붙이는 경우 추가 메모리 생성 없이 기존 문자열이 확장되는 클래스입니다.

String과 다르게 문자열이 빈번하게 변경될 때 사용하면 성능이 좋습니다.

StringBuilder클래스는 멀티쓰레드 환경에서 문자열의 안전한 변경을 보장해주지 않는 특징(not thread-safe)이 있습니다. 

즉, 여러 쓰레드가 문자열(공유자원)에 동시에 접근/변경이 이루어지면 수행결과가 올바르지 않는 것을 의미합니다. 

 

문자열 변경 시 메모리 상태

StringBuilder클래스를 생성하고 여기에 "test"문자열을 생성합니다.

그 후 append() 메소드를 통해 "1"과 "2" 문자열을 추가합니다. 

이 때 append() 메소드를 통해 1과 2가 새로 생성되는 것이 아닌 하나의 메모리에 문자열이 계속 이어붙여져 변경됩니다. 

 

코드 예시 

4행 ) StringBuilder sb 선언

5행 ) 문자열 sb가 할당된 메모리 주소 출력 

6,7행 ) 문자열 추가 

8행 ) 문자열 sb가 할당된 메모리 주소 출력

9행 ) StringBuilder 클래스를 String클래스로 변환

class Main{
	public static void main(String[] args) throws Exception
	{		
		StringBuilder sb = new StringBuilder("test");
		System.out.println(sb + " " + System.identityHashCode(sb)); //문자열과 메모리 주소 출력 
		sb.append("2");
		sb.append("3"); //문자열 추가 
		System.out.println(sb + " " + System.identityHashCode(sb));//문자열과 메모리 주소 출력
		String temp = sb.toString();
	}
}

 

실행 결과  

문자열 "test"에 "1"과 "2"를 추가하여도 문자열 주소가 변경되지 않는 것을 볼 수 있습니다. 

 

 

📌3. StringBuffer

StringBuffer 클래스는 StringBuilder와 마찬가지로 문자열을 이어붙이는 경우 추가 메모리 생성 없이 기존 문자열이 확장되는 클래스입니다. StringBuffer클래스는 멀티쓰레드 환경에서 문자열의 안전한 변경을 보장(thread-safe)하는 특징이 있습니다. Thread-safe란 멀티스레드프로그래밍에서 어떤 변수에 동시 접근이 이루어져도 프로그램 실행에 전혀 문제가 없음을 의미합니다.

* 두 스레드가 동시에 문자열을 접근하더라도 안전한 변경을 보장해줌

 

문자열 변경 시 메모리 상태

StringBuffer클래스를 생성하고 여기에 "testStr"문자열을 생성합니다.

그 후 append() 메소드를 통해 "1"과 "2" 문자열을 추가합니다. 

이 때 append() 메소드를 통해 1과 2가 새로 생성되는 것이 아닌 하나의 메모리에 문자열이 계속 이어붙여져 변경됩니다

 

코드 예시 

4행 ) StringBuffer sb 선언

5행 ) 문자열 sb가 할당된 메모리 주소 출력 

6,7행 ) append() 메소드를 통해 문자열 추가 

8행 ) 문자열 sb가 할당된 메모리 주소 출력

class Main{
	public static void main(String[] args) throws Exception
	{		
		StringBuffer sb = new StringBuffer("testStr");
		System.out.println(sb + " " + System.identityHashCode(sb));
		sb.append("2");
		sb.append("3");
		System.out.println(sb + " " + System.identityHashCode(sb));
	}
}

 

실행 결과  

StringBuffer 문자열 "testStr"에 "1"과 "2"를 추가하여도 문자열 주소가 변경되지 않는 것을 볼 수 있습니다. 

 

 

📌 4. 공통점/차이점

아래는 StringBuilder와 StringBuffer클래스의 공통점, 차이점을 정리한 표입니다.

StringBuilder와 StringBuffer클래스의 공통점은 둘다 "mutable"한 성질을 가지고 있다는 것입니다.

"mutable"이란 객체지향프로그래밍에서 가변 객체를 의미하며 생성 후에도 상태를 바꿀 수 있는 성질을 말합니다. 

(String클래스는 "immutable"한 성질을 가지고 있어 생성 후에 바꿀 수 없습니다)

StringBuilder는 싱글쓰레드환경에 적합하며, StringBuffer는 멀티쓰레드환경에 적합합니다. 

  StringBuilder StringBuffer
공통점  mutable : 문자열 변경시 새로운 메모리 필요 없이 변경 가능
차이점
싱글쓰레드환경 적합 멀티쓰레드환경 적합
스레드가 안전한 프로그램 개발시 사용 연산이 많을 경우 유리함