Programming/Java

Java 문자열을 다루는 클래스 String, StringBuilder, StringBuffer 차이점은 무엇일까?

Jan92 2021. 7. 16. 00:52

 

자바에서 문자열을 다루는 클래스는 String, StringBuilder, StringBuffer 세가지가 있습니다.

이 세가지 클래스의 차이점과 어떤 경우에 어떤 클래스를 사용하는 것이 적합한지 알아봅니다.

 

 

String

먼저 String 입니다. String은 불변 (immutable) 의 속성을 가지고 있습니다. 문자열이 변할 때 마다 새로운 객체 (인스턴스) 를 생성합니다.

 

StringBuilder, StringBuffer

반면 StringBuilder, StringBuffer는 가변 (mutable) 의 속성을 가지고 있습니다.

둘 다 문자열의 변경이 가능하며, 내부에 char 배열 공간이 존재하기 때문에 문자열의 크기가 늘어나면 자동으로 증가시켜주고, 배열이 꽉 차면 자동으로 늘려줍니다. 

String과 다르게 동일한 객체 (인스턴스) 에 덮어 쓰기 때문에 같은 해시 값을 가지며 효율성이 높습니다.

 

String, StringBuilder hashCode 비교

* hashCode는 메모리의 주소 값을 해시한 것으로 할당된 메모리마다 다르게 표시됩니다.

 

즉, 위 결과를 보면 String은 + 연산을 하며 새로운 메모리 주소 값을 갖게 되고, StringBuilder는 append() 연산을 해도 같은 메모리 주소 값을 가진다는 것을 알 수 있습니다.

 

 

그렇다면 StringBuilder와 StringBuffer의 차이점은 무엇일까요?

두 클래스의 차이점은 동기화 (Synchronization) 지원 여부의 차이입니다.

 

StringBuffer는 동기화를 지원하기 때문에 multi thread 에서 사용할 수 있고, 반면 StringBuilder는 동기화를 지원하지 않기 때문에 single thread 또는 thread를 신경쓰지 않아도 되는 환경에서 사용할 수 있습니다.

 

multi thread의 사용 여부를 모르는 상황이라면 안전성을 위하 StringBuffer를 사용하는 경우가 많다고 합니다.

하지만 확실하게 multi thread를 사용하지 않는 환경이라면 StringBuilder가 StringBuffer보다 연산 처리가 빠르기 때문에 환경에 따라 어떤 것을 사용할지 잘 판단할 필요가 있을 것 같습니다.

 

그리고 StringBuilder, StringBuffer를 생성할 경우 버퍼의 크기를 초기에 설정해줘야 하는데, 이러한 동작으로 인해 String 객체보다 생성 속도가 느려지게 됩니다. 문자열을 수정할 때도 버퍼의 크기를 늘리고, 줄이고, 명칭을 변경해야하는 내부적인 연산이 필요하므로 많은 양의 문자열 수정이 아니라면 String 객체를 사용하는 것이 오히려 나을 수 있습니다.

또한 String 클래스는 크기가 고정되어 있으므로 단순하게 읽는 조회 연산에서는 더 빠르게 읽을 수 있는 장점이 있습니다.

 

결론적으로 문자열 연산이 적을 경우에는 String을 사용하면 되고, 연산이 많다면 StringBuffer 또는 StringBuilder를 사용하면 됩니다.

 

(StringBuffer, StringBuilder 에서는 + 연산 대신 append() 라는 함수를 이용합니다.)

 

 

String, StringBuilder, StringBuffer 속도 비교

String, StringBuilder, StringBuffer 세 클래스의 속도 비교 입니다.

 

 

* JDK 1.5 이후 버전에서는 컴파일 단계에서 String 객체를 사용하더라도 StringBuilder로 컴파일 되도록 변경 되었기 때문에 StringBuilder와 성능상으로 차이가 없어졌습니다.

하지만 반복문을 사용하여 문자열을 더할 때는 마찬가지로 객체를 계속 추가하기 때문에 반복문을 사용하여 문자열을 더하는 경우에는 String 클래스 대신 StringBuffer 또는 StringBuilder를 사용하는 것이 좋습니다.