String, StringBuffer, StringBuilder는 Java에서 문자열을 처리하는 클래스입니다. 이들 클래스는 문자열을 표현하고 조작하는 다양한 메서드를 제공하지만, 몇 가지 차이점이 있습니다. 각 클래스의 차이점과 장단점을 살펴보겠습니다.
String은 객체이며, 한 번 생성되면 변경할 수 없는 불변(Immutable)성을 가진 불변 객체입니다.
String 객체에 새로운 문자열을 합치게 되면 기존 생성한 String 객체에 문자열을 이어 붙이는 것이 아니라 기존 문자열과 이어 붙인 문자열을 담은 새로운 String 객체를 생성하게 됩니다.
String 객체는 JVM 메모리 구조의 Heap 메모리 영역에 생성되며, 한 번 생성된 String 객체의 내용은 불변성 특징때문에 변경할 수 없습니다!
기존에 사용하지 않는 String 객체들은 GC(가비지 컬렉션)에 의해서 회수되기는 하지만, 문자열 연결 작업이 많은 경우 성능 측면에서 비효율적일 수 있으며, 많은 메모리가 사용될 수 있기 때문에 신중히 사용 할 필요가 있습니다.
StringBuffer와 StringBuilder의 공통점은 AbstractStringBuilder 추상 클래스를 상속받고 있다는 점입니다. 그렇다는 것은 StringBuffer와 StringBuilder는 공통의 API를 제공한다는 의미입니다.
문자열 연결 작업이 자주 발생하고 있다면 String 객체를 + 연산자로 연결하는 것이 아니라, StringBuffer와 StringBuilder 객체를 사용하는 것이 좋습니다.
StringBuffer와 StringBuilder의 차이점은 바로 스레드 안전성(Thread safe)입니다.
StringBuffer는 동기화(synchronized)되어 여러 스레드(Thread)에서 안전하게 사용할 수 있습니다. 즉, 멀티스레드 환경에서 동시에 접근하더라도 데이터 일관성을 보장한다는 것입니다.
반면, StringBuilder는 동기화(synchronized)되지 않아 멀티스레드 환경에서의 안정성을 보장하지 않습니다. 따라서 단일 스레드 환경에서 문자열 조작이 필요한 경우에는 StringBuilder를 사용하는 것이 더 효율적입니다!
메모리 효율성 측면에서는 String, StringBuffer, StringBuilder 순서로 메모리를 사용합니다. String은 불변이기 때문에 문자열 조작 시마다 새로운 객체를 생성하기 때문에 이후에 메모리 낭비를 초래할 수 있습니다!
StringBuffer와 StringBuilder는 가변이기 때문에 내부적으로 버퍼를 사용하여 문자열을 조작합니다. 문자열 조작이 빈번한 경우에는 StringBuffer와 StringBuilder가 메모리 효율성 측면에서 더 좋은 선택일 수 있습니다.
따라서 정리하자면 !!
문자열을 변경하지 않고 읽기만 하는 경우에는 String 객체를 사용한다!
문자열 연결 작업이 자주 발생하고 단일 스레드 환경이다? StringBuilder를 사용!
StringBuilder와 같지만, 멀티 스레드 환경에서 사용한다! 그렇다면 StringBuffer를 사용하도록 합시다!