본문 바로가기

Java

Java String, StringBuilder, StringBuffer 각각의 차이점 정리

Java에서 문자열을 다룰 때 자주 등장하는 클래스가 있다.

- String

- StringBuilder

- StringBuffer

 

겉으로 보기에는 모두 문자열을 다루는 클래스처럼 보이지만, 내부 동작 방식과 사용 목적은 꽤나 다르다

특히 문자열을 자주 변경하거나 이어 붙이는 코드에서는 어떤 크래스를 선택하느냐에 따라 성능 차이가 발생할 수 있다

 

이번 글에서는 String, StringBuilder, StringBuffer의 차이를 정리해 보겠다.

 

1. String 

String은 Java에서 가장 기본적으로 사용하는 문자열 클래스이다.

String str = "hello";
str = str + "Java";

 

위 코드를 보면 str에 "Java"를 이어 붙인 것처럼 보인다

하지만 실제로 기존 "Hello" 문자열이 변경되는 것은 아니다

 

String은 불변 객체, 즉 immutable 객체이다

한 번 생성된 문자열의 값은 변경할 수 없다

 

따라서 문자열을 수정하는 것처럼 보이는 연산은 실제로는 새로운 String 객체를 생성한다

 

String str = "Hello";
str += "Java";
str += "World";

 

이 코드는 문자열을 계속 변경하는 것처럼 보이지만, 내부적으로는 매번 새로운 문자열 객체가 만들어질 수 있다

그래서 반목문 안에서 문자열을 계속 이어 붙이는 경우에는 성능상 좋지 않을 수 있다

String result = "";
for(int i = 0; i < 10000; i++) {
	result += i;
}

이런 코드는 많은 문자열 객체를 생성할 수 있기 때문에 비효율적이다

 

2. StringBuilder

StringBuilder는 문자열을 효율적으로 변경하기 위해 사용하는 클래스이다

StringBuilder sb = new StringBuilder();

sb.append("Hello");
sb.append("Java");
sb.append("World");

String result = sb.toString();

 

  • StringBuilder는 String과 다르게 가변 객체, 즉 mutable 객체이다.
  • 문자열을 추가하거나 수정할 때마다 새로운 객체를 만드는 것이 아니라, 내부 버퍼를 이용해 값을 변경한다
  • 그래서 문자열을 여러 번 이어 붙이는 작업에서는 String보다 훨씬 효율적이다
StringBuilder sb = new StringBuilder();

for(int i = 0; i < 10000; i++) {
	sb.appent(i);
}

String result = sb.toString();

단, StringBuilder는 스레드가 안전하지 않다.

즉, 여러 스레드가 동시에 같은 StringBuilder 객체를 수정하는 상황에서는 문제가 발생할 수 있다

하지만 일반적인 단일 스레드 환경이나 메서드 내부에서만 사용하는 경우에는 대부분 StringBuilder를 사용하면 된다

 

3. StringBuffer

StringBuufer는 StringBuilder와 거의 비슷한 역할을 한다

StringBuffer sb = new StringBuffer();

sb.append("Hello");
sb.append("Java");
sb.append("World");

String result = sb.toString();

 

  • SStringBuffer 역시 가변 객체이다
  • 문자열을 여러 번 수정하거나 이어 붙일 때 사용 가능하다
  • StringBuilder와 가장 큰 차이는 스레드 안정성이다
  • StringBuffer의 주요 메서드는 sychronized로 동기화되어 있다
  • 그래서 여러 스레드가 동시에 접근해도 안전하게 사용 가능하다

하지만 동기화 처리가 들어가기 때문에 일반적으로 StringBuilder보다 성능은 느릴 수 있다

 

 

그렇다면 언제 무엇을 사용해야 할까?

 

정리하면 다음과 같이 선택하면 된다

 

String을 사용하는 경우

문자열 값이 자주 변경되지 않는 경우에는 String을 사용하면 된다

String name = "Java";
String message = "Hello Java"

일반적인 문자열 표현에는 대부분 String을 사용한다

 

StringBuilder를 사용하는 경우

문자열을 반복해서 이어 붙이거나 수정해야 한다면 StringBuilder를 사용하는 것이 좋다

StringBuilder sb = new StringBuilder();

for(int i = 0; i < 100; i++) {
	sb.append(i);
}

String result = sb.toString();

실무에서는 대부분의 문자열 조립 작업에 StringBuilder를 사용한다

 

 

StringBuffer를 사용하는 경우

여러 스레드가 동시에 같은 문자열 객체를 수정해야 한다면 StringBuffer를 사용할 수 있다

StringBuffer sb = new StringBuffer();

sb.appent("thread safe");

 

  • 다만 실제로 이런 상황은 많지 않기 때문에, 특별히 멀티스레드 환경에서 공유해야 하는 경우가 아니라면 StringBuilder를 더 자주 사용한다