슬기로운 개발생활

[Java] String, StringBuffer, StringBuilder 차이와 장단점

by coco3o
반응형
String, StringBuffer, StringBuilder

Java에서 문자열을 다루는 대표적인 클래스로 String, StringBuffer, StringBuilder가 있다.

알아보기에 앞서 이 클래스들의 공통점은 모두 다 String(문자열)을 저장하고 관리하는 클래스들이 라는 것이다.

 

연산이 많지 않을때는 위에 나열된 어떤 클래스를 사용하더라도 이슈가 발생할 가능성은 거의 없다.

그러나 연산횟수가 많아지거나 멀티쓰레드, Race condition 등의 상황이 자주 발생한다면,

각 클래스의 특징을 이해하고 상황에 맞는 적절한 클래스를 사용해야 할 것이다.

 

String   vs   StringBuffer / StringBuilder

String과 StringBuffer/StringBuilder 클래스의 가장 큰 차이점은 String불변(immutable)의 속성을 갖는다는 점이다.

아래의예제에서 "hello" 값을 가지고 있던 String 클래스의 참조변수 str이 가리키는 곳에 저장된 "hello"에 "world" 문자열을 더해

"hello world"로 변경한 것으로 착각할 수 있다.

String  str  =  "hello";       //  String str = new String("hello");
str  =  str  +   "world";        //  [  hello  world  ]

하지만 기존에 "hello"값이 들어가있던 str이 "hello world"라는 값을 가지고 있는 새로운 메모리영역을 가리키게 변경되고,

처음 선언했던 "hello"로 값이 할당 되어 있던 메모리 영역은 Garbage로 남아있다가 GC(garbage collection)에 의해 사라지게 된다.

String 클래스는 불변하기 때문에 문자열을 수정하는 시점에 새로운 String 인스턴스가 생성된 것이다.

출처 : https://ifuwanna.tistory.com/221

위와 같이 String은 불변성을 가지기 때문에 변하지 않는 문자열을 자주 읽어들일 경우 String을 사용하면 좋은 성능을 발휘한다.

그러나 문자열 추가, 수정, 삭제 등의 연산이 빈번하게 발생하는 경우에 String 클래스를 사용하면 힙 메모리(Heap)에 많은 Garbage가 생성되어 힙 메모리 부족으로 성능에 치명적인 영향을 끼친다.

 

이를 해결하기 위해 Java에서는 가변(mutable)성을 가지는 StringBuffer StringBuilder 클래스를 도입했다.

String 과는 반대로 StringBuffer / StringBuilder 는 가변성을 가지기 때문에 .append( )  .delete( ) 등의 API를 이용하여

동일 객체 내에서 문자열을 변경하는 것이 가능하다. 따라서 문자열의 추가, 수정, 삭제가 빈번하게 발생할 경우라면

String 클래스가 아닌 StringBuffer / StringBuilder를 사용해야 한다.

StringBuffer  sb  =  new  StringBuffer("hello");
sb.append("world");

출처 : https://ifuwanna.tistory.com/221

StringBuffer   vs   StringBuilder

동일한 API를 가지고 있는 StringBufferStringBuilder의 차이점은 무엇일까?

가장 큰 차이점은 동기화의 유무로써 StringBuffer는 동기화 키워드를 지원하여 멀티쓰레드 환경에서 안전(thread-safe)하다.

참고로 String도 불변성을 가지기 때문에 마찬가지로 멀티쓰레드 환경에서의 안정성(thread-safe)을 가지고 있다.

 

반대로 StringBuilder는 동기화를 지원하지 않기 때문에 멀티쓰레드 환경에서 사용하는 것은 적합하지 않지만

동기화를 고려하지 않는 만큼 단일쓰레드에서의 성능은 StringBuffer보다 뛰어나다.

 

결론

단순히 성능만 놓고 본다면 연산이 많은 경우

StringBuilder  >  StringBuffer  >>>  String 정도로 보면 된다.

하지만 각 클래스들은 성능 이슈 외에도 사용 편의성, 멀티 스레드 환경 등 여러가지 고려해야할 요인이 있으므로

아래와 같은 경우에 맞게 사용하면 될 것이다.

 

String   :  문자열  연산이  적고  멀티쓰레드  환경일  경우

StringBuffer   :   문자열  연산이  많고  멀티쓰레드  환경일  경우

StringBuilder   :   문자열  연산이  많고  단일쓰레드이거나  동기화를  고려하지  않아도  되는  경우  

출처 : https://ifuwanna.tistory.com/221

 

반응형

블로그의 정보

슬기로운 개발생활

coco3o

활동하기