불변과 가변, thread-safe와 performance
String 은 불변객체이며, StringBuilder/Buffer 는 가변객체이다.
StringBuilder 는 성능이 좋지만 StringBuffer 처럼 thread-safe 하진 않다.
불변하는 Unicode Character 의 집합(문자열)이다.
다른 클래스 자료형과는 달리, String 은 문자열 리터럴을 직접 String 변수에 대입할 수 있다
문자열 리터럴은 특별히 Heap 메모리 내에 존재하는 StringPool 에 저장된다.
리터럴이 뭔가요?
변수에 넣는 데이터 자체를 말한다. 상수와 헷갈릴 수 있는데, 상수는 변하지 않는 변수이다.
힙 메모리에 저장되는것들이라 생각하면 편하다.
또한, +
연산자에 대한 재정의가 존재한다. [링크 참조] [링크 참조2]
Java 1.5 이전에는 StringBuffer 의 append 로,
Java 1.5 이후에는 StringBuilder 의 append로, 재정의하였으며
Java 1.9 이후에는 StringConcatFactory 를 통해 concat 연산 자체를 추상화하였다.
가변하는(변환가능한) 문자열 객체이다.
리터럴로 생성된 String 과는 달리공유되지 않는 자원으로, 변화에 대한 side-effect 가 발생하지 않는다.
다만, StringBuilder 는 멀티스레드환경에서 동기화를 지원하지 않는 대신 동기화 오버헤드가 없어 효율적이고,
StringBuffer 는 내부적으로 synchronized 키워드를 사용하여 thread-safe 하지만 전술한 이유로 인해 성능이 비교적 좋지 않다.
놀랍게도 StringBuffer 가 StringBuilder 보다 오래되었다
String 은 불변객체이며, StringBuilder 와 StringBuffer 는 가변객체이다.
String 의 합연산(concat)은 AbstactStringBuilder 를 구현한 인스턴스를 생성하여 append 메서드를
호출시키기 때문에, StringBuilder 와 StringBuffer 의 append 메서드보다 성능이 떨어진다.