문자열 클래스(String & StringBuffer & StringBuilder)
String
- new 연산자를 통해 생성된 인스턴스의 할당된 메모리 공간은 변하지 않는다. (Immutable)
- '+' 연산 또는 concat method를 통해 기존에 생성된 String 객체에 다른 문자열을 붙여도 기존 문자열에 새로운 문자열을 붙이는 것이 아닌, 새로운 String 객체를 생성 후 이 객체에 연결된 문자열을 저장하고, 그 객체를 참조하도록 한다. - JDK 1.5 이후 반복 루프 사용 시 해당
- 문자열 연산이 많이 일어나는 경우, 더 이상 참조되지 않는 기존 객체는 Garbage Collection에 의해 제거 되어야 하기 때문에 성능이 좋지 않다.
- 문자열 연산 시 새로 객체를 만드는 Overhead가 발생한다.
- 객체가 불변하므로, Multi thread에서 동기화를 신경 쓸 필요가 없다. (조회 연산에 매우 큰 장점)
- String : 문자열 연산이 적고, 조회가 많은 Multi-Thread 환경에서 좋다.
StringBuffer & StringBuilder
- 공통점
- new 연산자로 클래스를 한 번에 만든다. (Mutable)
- 세팅 된 문자열 값을 변경할 수 없는 String class 단점을 보완
- 문자열 연산 시 새로 객체를 만들지 않고, 크기를 변경 시킨다.
- StringBuffer와 StringBuilder 클래스의 메서드가 동일하다.
- 차이점
- StringBuffer는 Multi Thread 환경에서 Thread-Safe 하다 (동기화 가능)
- StringBuilder는 Multi Thread 환경에서 Thread-Safe 하지 않다 (동기화 불가능)
- StringBuffer : 문자열 연산이 많은 Multi-Thread 환경에서 좋다.
- StringBuilder : 문자열 연산이 많은 Single-Thread 또는 Thread를 신경 안 쓰는 환경에서 좋다.
Conclustion
<aside>
💡 String Class는 JDK 1.5버전 이전에 문자열 연산('+', concat)을 할 때에는 조합된 문자열을 새로운 메모리에 할당하여 참조함으로 인해서 성능 상의 이슈가 있었다. 그러나 JDK1.5 버전 이후에는 컴파일 단계에서 String 객체를 사용하더라도 StringBuilder로 컴파일 되도록 변경되었다. 그리하여 JDK 1.5 이후 버전에서는 String 클래스를 활용해도 StringBuilder와 성능 상으로 차이가 없어졌다. 하지만 반복 loop를 사용해서 문자열을 더할 때에는 객체를 계속 추가한다는 사실에는 변함이 없다.
</aside>
- String class 보다는 Thread-Safe와 관련이 있으면 StringBuffer를 사용
- Thread-Safe와 상관이 없으면 StringBuilder를 사용 권장
- 단순히 성능만 놓고 본다면 연산이 많은 경우 : StringBuilder > StringBuffer >>> String