String 클래스는 불변(immutable) 클래스이다. 즉, String 객체는 한 번 생성되면 변경할 수 없다.
String
String str = "Hello";
str = str + " world";
System.out.println(str); // Hello world
위 코드를 보면 String의 값이 변경된 것처럼 보이지만 문자열 수정 시점에 값이 할당되어 있던 메모리 영역은 Garbage로 남아있다가 GC(Garbage Collection, 가비지 컬렉션)에 의해 사라지고, 새 메모리 영역을 참조한다.
즉, 문자열을 추가하면 실제로는 새로운 String 객체가 생성되고, 기존의 String 객체는 변경되지 않는다.
StringBuffer 클래스는 가변(mutable) 문자열을 다루는 클래스이다. 내부적으로 문자열을 수정할 수 있도록 설계되어 있으며, 스레드 안전(Thread-safe) 하도록 동기화(synchronized) 기능을 제공한다.
StringBuilder 클래스는 StringBuffer와 매우 유사하지만 스레드 안전성이 없는 가변 문자열 클래스이다. 즉, 멀티스레드 환경에서는 사용하는 것을 지양해야 한다.
요약
String은 불변 객체이므로 문자열이 자주 수정되지 않는 경우에 적합하다. 불변성 덕분에 멀티스레드 환경에서 안전하게 사용할 수 있다.
StringBuffer는 가변 객체로, 멀티스레드 환경에서 안전하게 문자열을 수정할 수 있지만 동기화로 인한 성능 저하가 있을 수 있다.
StringBuilder는 StringBuffer와 비슷하지만 동기화가 없어서 성능이 더 좋다. 그러나 멀티스레드 환경에서는 안전하지 않으므로, 단일 스레드 환경에서만 사용해야 한다.
따라서, 문자열을 자주 변경해야 할 경우 StringBuilder를 사용하는 것이 일반적으로 가장 효율적이며, 멀티스레드 환경에서 안전성을 보장하려면 StringBuffer를 사용하고, 문자열이 변하지 않거나 변경이 적은 경우에는 String을 사용하는 것이 적합하다.