String, StringBuffer, StringBuilder 의 특징
String, StringBuffer, StringBuilder 이 세가지 클래스들은 모두 문자열 처리를 위한 클래스 이다.
대부분의 자바를 처음 공부하는 사람들은 문자열 처리를 위해서 String 클래스만을 사용하며 조금더 공부하여 StringBuffer 클래스를 알게되면 정확한 차이를 모르는채 성능 향상이라는 이유로 StringBuffer 클래스를 자주 사용한다.
그렇다면 이 세가지 클래스에 정확한 차이점을 알아보고 상황에 맞게 잘 사용해 보도록 하자
String 클래스
String 클래스와 다른 2개의 클래스와의 가장 큰 차이점은 String 클래스는 immutable(불변) 하고 StringBuffer, StringBuilder 클래스는 mutable(가변) 한다는 점이다.
이게 무슨 말인지 쉽게 설명 하자면 String 객체는 한번 생성되면 할당된 메모리 공간이 변하지 않는다.
+연산자 또는 문자열에 변화를 줘도 메모리 공간이 변하는 것이 아니라 새로운 String 객체를 만든 후, 새 String 객체에 연결된 문자열을 저장하고 그객체를 참조하도록 한다.
변경되기 전의 문자열은 더이상 어느곳에서도 참조하지 않게 되면 가비지 콜렉터(언제 제거될지 모름)에 의해 제거 된다.
이러한 이유로 String 객체는 문자열 연산이 많아질 때 성능이 떨어질 수 밖에 없는 단점이 있다.
그렇다면 왜 이러한 단점을 가지면서도 immutable(불변) 클래스인 String 클래스를 기본 문자열처리 클래스로 정했을까?
immutable(불변) 클래스의 가장 큰 장점은 안전하게 공유될 수 있다는 점이다.
즉, 변경은 적고 읽기만 많은 경우, 또는 여러 쓰레드나 객체에서 공유하는 경우, synchronization(동기화)와 같은 특별한 안전장치 없이도 안전하게 공유 될수 있다.
대부분의 문자열이 복잡한 문자열 처리과정보다는 한번 설정된 문자열들을 여러 곳에서 공유하는 경우가 많으므로, 자바에서 기본 문자열을 처리하는 클래스로 String 클래스를 immutable 패턴으로 설정하였다.
StringBuffer, StringBuilder 클래스
StringBuffer, StringBuilder 클래스는 String 과 다르게 mutable(가변) 클래스이다.
즉 문자열 연산에 있어서 클래스를 한번만 만들고 연산이 필요할 때 크기를 변경시켜 문자열을 변경한다. 이 경우 객체를 새로 생성하지 않는다.
그러므로 문자열 연산이 자주 있을 때 String 클래스 대신 사용하면 성능이 좋다는 장점이 있다.
StringBuilder는 JDK 5.0 에서 새로 추가된 클래스이다.
두 클래스에서 제공하는 메소드는 동일하다.
차이점은 StringBuffer는 멀티쓰레드환경에서 synchronized키워드가 가능하므로 동기화가 가능하다. 즉, thread-safe하다.
StringBuilder는 동기화를 지원하지 않기 때문에 멀티쓰레드환경에서는 적합하지 않다. 대신 StringBuilder가 동기화를 고려하지 않기 때문에 싱글쓰레드 환경에서 StringBuffer에 비해 연산처리가 빠르다.
String, StringBuffer, StringBuilder 선택 기준
String 객체는 불변이기 때문에 변하지 않는 문자열은 String을 사용한다.
StringBuilder는 비동기방식이기 때문에 Single Thread 환경하에서, 변화되는 문자열의 사용한다.
StringBuffer 동기방식으로 저장되기 때문에 멀티쓰레드로 접근하거나 문자열이 변경될 경우에 사용한다.
JDK 버전에 따른 차이
JDK 1.5버전 이후에는 컴파일 단계에서 String 객체를 사용하더라도 StringBuilder로 컴파일 되도록 변경 되었다.
그렇기 때문에 String 클래스를 활용해도 성능차이가 없어지긴 하였지만 반복 루프를 사용해 문자열을 더할때 객체를 게속 추가하는 사실에는 변함이 없다.
따라서 String 클래스를 쓰는 대신, 스레드와 관련이 있으면 StringBuffer를, 스레드 안전 여부와 상관이 없으면 StringBuilder를 사용하는 것을 권장한다.