String 정의와 특징
- Java에서 String 클래스는 불변성을 갖습니다. 그래서 변하지 않는 문자열을 자주 사용하는 경우엔 좋은 성능을 기대할 수 있습니다.
- 하지만 문자열에 대한 변경이 자주 일어나는 프로그램에서 String만 사용하게 된다면 효율적인 성능을 기대하기 어렵습니다.
- 그래서 우리는 StringBuilder , StringBuffer을 사용하여 효율적인 성능을 보일 수 있습니다.
String vs String Builder vs String Buffer
- Java에서 String 객체는 한번 값이 할당되면 그 공간은 변하지 않습니다.
- Stringbuilder나 StringBuffer 객체는 한번 값이 할당되더라도 한번 더 다른 값이 할당되면 할당된 공간이 변하는 특성을 갖고 있습니다.
String
- 불변성을 갖는다. → Immutable 하다.
- String 을 리터럴 값으로 할당하는 경우엔 Heap 메모리 영역안의 특별한 메모리 공간인 String constant pool 에 저장된다.
- 만약 String constant pool에 존재하는 리터럴 값을 사용하게 된다면 새롭게 리터럴 값을 만들어 String constant pool에 저장하는 것이 아닌, 현재 존재하는 값을 사용하게 됩니다.
- new 키워드를 통해 String 변수에 값을 할당하게 되면 일반적인 객체와 동일하게 Heap 영역에 동적으로 메모리 공간이 할당되게 됩니다.
- 마찬가지로 같은 문자열이더라도 new 키워드를 한번 더 사용하게 되면 같은 값이지만 다른 메모리 공간(Heap 영역 안)을 참조하게 됩니다.
String Builder, String Buffer
- 가변성을 갖는다. → mutable 하다.
String Builder vs String Buffer
- 두 클래스 모두 AbstractStringBuilder 라는 추상 클래스를 상속받아 구현되어 있다.
- StringBuilder와 StringBuffer 클래스의 문자열을 수정하고 싶으면 append() 메서드를 사용하게 되는데요.
public AbstractStringBuilder append(String str) {
if (str == null) {
return appendNull();
}
int len = str.length();
ensureCapacityInternal(count + len);
putStringAt(count, str);
count += len;
return this;
}
- 다음과 같이 StringBuilder , StringBuffer에 문자열을 추가하게 되면 추가할 문자열의 크기(길이)만큼 현재의 문자열을 저장하는 배열의 공간을 늘려주고, 늘려준 공간에 추가할 문자열을 넣어주는 방식으로 되어있습니다.
- 위에서 살펴본 내부동작을 통해 값이 변경되더라도 같은 주소공간을 참조하게 되는 것이며, 값이 변경되는 가변성을 띄게 되는 것입니다.
차이점
- 두 클래스의 기능은 동일하지만 한 가지 차이점이 존재합니다. 바로 동기화(Synchronization)의 문제입니다.
- StringBuilder는 동기화를 지원하지 않는 반면, StringBuffer는 동기화를 지원하여 멀티 스레드 환경에서도 안전하게 동작할 수 있습니다.
- 그 이유는 StringBuffer는 메서드에서 synchronized 키워드를 사용하기 때문인데요.
언제 사용할까?
String
- 변하지 않는 문자열을 자주 사용할 경우 String 타입을 사용하는 것이 성능면에서 유리할 것 입니다.
String Builder
- StringBuilder는 동기화를 지원하지 않는 반면, 속도면에선 StringBuffer 보다 성능이 좋습니다.
- 그렇기 때문에 우리는 단일 스레드 환경 과 문자열의 추가, 수정, 삭제 등이 빈번히 발생하는 경우StringBuilder를 사용하는 것이 성능면에서 유리할 것입니다.
String Buffer
- StringBuffer는 동기화를 지원하여 멀티 스레드 환경에서도 안전하게 동작할 수 있습니다.
- 그렇기 때문에 우리는 멀티 스레드 환경 과 문자열의 추가, 수정, 삭제 등이 빈번히 발생하는 경우StringBuffer를 사용하는 것이 성능면에서 유리할 것입니다.