Java StringBuffer, StringBuilder 사용법 및 차이점 - 자바 동적 문자열
- Java에서 문자열을 다루는 대표적인 클래스로 String, StringBuffer, StringBuilder가 있습니다.
연산이 많이 이루어지지 않을 때에는 어떤 클래스를 사용해도 이슈에 무방하지만, 연산이 많아지거나 멀티쓰레드 등의 상황이 자주 발생한다면 각 클래스의 특징을 이해하고 상황에 맞게 적절하게 사용해야 합니다.
1. String vs StringBuffer / StringBuilder
먼저 String은 불변의 속성
을 가집니다.
String str = "hello"; // String str = new String("hello");
str += "world"; // "hello world"
위와 같이 문자열에 문자열을 더할 수 있는데 불변..?? 이라는 생각이 들 수 있습니다.
"hello"값을 가지고 있던 String 클래스의 참조변서 str이 가르키는 곳에 "world"문자열을 더해 "hello world"로 변경 된 것으로 착각하는 것입니다.
실제로는 "hello"값이 들어가 있던 String 클래스의 참조변수 str이 "world"가 추가된 "hello world"의 값으로 새로운 메모리의 영역을 가르키게 변경되는 것 입니다.
그리고 처음 선언했던 "hello"로 값이 할당되어있던 메모리 영역은 Garbage로 남아 있다가 GC(garbage collection)에 의해 사라지게 되는 것 입니다.
이제 불변이라는 것이 이해가 되시나요?
String 클래스는 불변하기 때문에 문자열을 수정하는 시점str += "world";
에 새로운 String 인스턴스(instence)가 생성되는 것 입니다.
위 설명과 같이 String은 불변의 속성을 가지기 때문에 변하지 않는 문자열을 자주 읽어들이는 경우에 String 클래스의 사용이 적합하다고 볼 수 있습니다.
그러나 문자열의 추가, 수정, 삭제 등의 연산이 자주 일어나는 경우에 String 클래스를 사용하게 되면 힙 메모리(Heap)에 많은 임시 가비지(Garbage)가 생성되어 힙 메모리 부족으로 성능에 치명적인 영향을 끼칠 수 있게 됩니다.
위 문제를 해결하기 위해 가변의 속성
을 가지는 StringBuffer
/ StringBuilder
클래스를 적합하게 사용할 수 있습니다.
String과는 반대로 StringBuffer / StringBuilder 는 가변성을 가지기 때문에 .append() .delete() 등의 API를 활용하여 동일 객체 내부에서 문자열 값을 변경할 수 있습니다.
StringBuffer sb= new StringBuffer("hello");
sb.append(" world");
위와 같이 append() 메서드를 사용하여 " world"를 파라미터로 전달하면 기존에 할당된 메모리 주소 그대로 값을 변경할 수 있습니다.
2. StringBuffer vs StringBuilder
그렇다면 동일한 API를 가지고 있는 StringBuffer와 StringBuilder의 차이점은 무엇일까요?
둘의 가장 큰 차이점은 동기화의 유무입니다.
StringBuffer는 동기화 키워드를 지원하여 멀티쓰레드 환경에서 안전하다는 장점을 가집니다. (String도 불변성을 가지기 때문에 동일한 강점을 가집니다.)
하지만 StringBuilder는 동기화를 지원하지 않기 때문에 멀티쓰레드 환경에서는 적합하지 않지만 단일쓰레드의 환경에서는 StringBuffer보다 우수한 성능을 보입니다.
정리
각 클래스별 특징을 정리해 보겠습니다.
일반적인 경우에는 아래와 같은 상황에 맞게 사용하면 될 것 입니다.
String | 문자열 연산이 적고 멀티쓰레드 환경일 경우 |
StringBuffer | 문자열 연산이 많고 멀티쓰레드 환경일 경우 |
StringBuilder | 문자열 연산이 많고 단일쓰레드거나 동기화 고려가 필요 없을 때 |
'Programming > Java' 카테고리의 다른 글
[Java] 제네릭(Generic) 사용법 / 개념 및 예제 정리 (0) | 2021.03.25 |
---|---|
[Java] 문자열(알파벳) 대문자 / 소문자로 변환 toUpperCase(), toLowerCase() (0) | 2021.03.25 |
[Java] 자료구조 - 스택(Stack)이란 무엇인가? (스택 개념, 연산, 구현) (0) | 2021.03.22 |
[Java] 객체지향 언어, 클래스와 객체, 인스턴스, 객체의 생성과 사용, 객체 배열 (0) | 2020.11.11 |
[Java] 조건문/반복문을 이용해 배수가 아닌 수 찾기 (0) | 2020.11.10 |