주의
이 문건은 과거 Hexo 블로그 (2017-10-31) 에서 이동된 문서입니다.
시간이 지남에 따라 최신 기술과 다를 수 있으니 주의 바랍니다.
문서를 시작하면서...
Java를 사용할 때 본인의 경우 가장 많이 사용하는 클래스는 아무래도 String이 아닐까 싶습니다.
String을 쓰다보면 문자열을 새로 문자열을 넣거나 또는 변경을 하는 경우 subString() 또는 split() 를 주로 사용합니다.
이것을 찾다보면 같이 마주치는 것은 StringBuffer 또는 StringBuilder가 있을 것입니다.
아마 면접질문 (신입 또는 주니어급 개발자)으로 저 세 가지의 차이점을 물어보는 경우가 많을 것입니다.
이번 포스팅을 통해서 한번 정리를 해보려 합니다.
Java의 String.
이번 포스팅에서는 Java의 String을 집중적으로 포커싱을 하는 글은 아니니 간략하게만 확인하고 넘어가도록 하겠습니다.
String은 일단 **불가변적(Immutable)**입니다.
이걸 쉽게 설명하자면 값을 변경하는 것이 불가능하다는 이야기입니다.
하지만 우리는 이런 사실을 잊고 아래와 같이 자연스럽게 사용합니다.
String testStr = "Hello World";
testStr = "Hello One";
위 선언 중 첫 번째 줄에서는 testStr에 "Hello World"라는 문자열의 값이 들어가게 됩니다.
하지만 두번 째 라인에서는 testStr에는 "Hello One" 문자열이 들어갑니다.
위와 같은 작업을 할 때는 기존의 testStr 객체의 메모리 공간에 "Hello World"의 내용을 변경하는 것이 아닌,
기존의 공간에서 새로운 공간을 할당한 후 문자열을 생성합니다.
결국 저장된 문자열을 변경하는 것이 아닌 새로운 객체를 만들어서 반환하는 것입니다.
이것을 가리켜 불가변적(Immutable) 이다 라고 표현합니다.
물론 이 불가변적(Immutable)인 객체는 사용이 간단하고, 멀티 쓰레드 환경에서 자유롭게 쓸 수 있는 장점이 있지만,
엄청난 양의 문자열을 변경하거나 치환을 하는 작업을 하게 될 경우 효율에 문제가 생길 수 있음을 예상할 수 있습니다.
이런 문제를 봉착하게 되면 우리는 검색할 때 다음의 키워드를 확인하게 됩니다.
StringBuffer, StringBuilder. 우리는 String의 친척
위에서 확인한 String 의 경우 문자열 변경을 하는 것이 아닌 새로 객체를 생성하여 반환함을 확인하였습니다.
만약 당신이 엄청난 문자열 연산을 하게 될 예정이라면 지금 소개하는 StringBuffer 또는 StringBuilder를 사용하면 됩니다.
StringBuffer testStr = new StringBuffer("Hello Wolrd";);
testStr.delete(5,10);
위의 경우는 StringBuffer로 생성한 testStr을 delete 메서드를 사용하여 문자열을 변경한 예제입니다.
testStr의 경우 결국 "Hello" 라는 문자열만 남게 될 것입니다.
즉 새롭게 생성을 하는 것이 아닌 기존의 객체에서 문자열 변경을 하는 것입니다.
이 StringBuffer나 StringBuilder의 경우 문자열 연산을 진행하며 버퍼 공간이 부족한 경우, 기존의 버퍼 크기를 늘리며 동작합니다.
만약 작은 규모의 String의 문자열 변경의 경우 자꾸 변경할 경우 문자열 객체를 만들고 지우고를 반복하니
성능에 문제가 있지 않을까 싶지만...
이런 경우 그냥 String을 사용해도 무방합니다.
변경을 위한 연산을 진행하는 비용보다 새로 메모리 공간을 할당해서 사용하는 비용이 더 낮기 때문입니다.
위에서도 이야기 하였지만 엄청난 문자열 변경 연산을 할 경우에만 StringBuffer, StringBuilder를 사용하는 것이 좋습니다.
StringBuffer, StringBuilder 너희 둘의 차이점?
그런데 이 두 가지의 차이점은 무엇일까요?
StringBuffer의 경우 동기화(Synchronization)를 보장하고,
StringBuilder의 경우 동기화(Synchronization)를 보장하지 않습니다..
즉 Multi Thread 환경에서는 StringBuffer 를 사용하고,
Single Thread 환경에서는 StringBuilder를 사용하면 됩니다.
새로운 부분
과거 JDK 1.5 버전에서는 String에서 문자열 연산(+, concat 등)을 할 때 성능상의 이슈가 있었지만,
JDK1.5 버전 이후부터는 컴파일 단계에서 String 객체의 문자열 연산을 사용할 경우 StringBuilder로 컴파일 되도록 변경되었습니다.
결론
String은 짧은 문자열을 더하거나, 간단한 문자열 처리를 할 때 사용하고,
StringBuffer는 쓰레드에 안전한 프로그램이 필요할 때나, 개발 중인 시스템의 부분이 쓰레드에 안전한지 모를 경우 사용합니다.
StringBuilder는 쓰레드에 안전성 여부에 관계가 없는 소프트웨어를 개발할 때 사용합니다.