목표
1. JAVA의 3가지 문자열 클래스에 대해 설명할 수 있다.
2. 각 문자열 클래스의 차이점에 대해 설명할 수 있다.
3. 상황에 맞게 문자열 클래스를 사용할 수 있다.
String / StringBuffer / StringBuilder
String | StringBuffer | StringBuilder | |
저장 공간 | 힙 또는 Constant String Pool | 힙 | 힙 |
변경유무 | 불변 | 가변 | 가변 |
Thead Safe | O | O | X |
Constant String Pool 이란?
- 자바에서 스트링을 생성하는 방법에는 두 가지가 있다. String literal로 생성하는 것과 new String으로 생성하는것.
- String literal로 생성하면 String 값은 힙 영역 내에 있는 "String Constant Pool"에 저장된다.
- new 연산자로 생성하면 Heap영역에 저장된다.
- String literal로 같은 문자열을 생성하는 경우 같은 주소값을 갖게 된다.
- 생성하려는 String의 값이 이미 String Constant Pool에 있다면, 해당 객체는 String Pool안에 존재하는 reference를 참조한다.
Thread Safe 란?
- 멀티 스레드 프로그래밍에서 어떤 함수나 변수, 객체가 여러 스레드로부터 동시에 접근이 이루어져도 프로그램의 실행에 문제가 없음을 말한다.
- 어떠한 객체가 한 스레드에 의해 사용 중일때, 다른 스레드가 그 객체를 사용하더라도 올바른 결과값이 나와야한다.
String Class
String객체는 한 번 생성되면 할당된 메모리 공간이 변하지 않는다. '+'연산 이나 concat 메소드를 사용해서 기존에 생성된 String 객체에 다른 문자열을 붙여도 기존 문자열에 새로운 문자열을 붙이는 것이 아니라 새로운 String 객체를 만든 후, 문자열을 저장하고, 그 객체를 참조하도록 한다.
자바의 API 문서를 찾아보니
반환값으로 String을 가지고 있었다. 사실 한번도 생각해보지 않고 그냥 매번 아무생각 없이 사용만 했었는데, 문서를 보니 그럼 리턴 값에 따라서 자기 자신을 바꾸는 함수인지 새로운 객체를 생성해서 반환하는 함수인지 구별할 수 있지 않을까? 라는 생각이 들었다.
장점
- 불변이라는 속성으로 인해 단순히 읽는 조회연산에서는 타 클래스보다 더 빠르게 읽을 수 있다.
- 불변하기 때문에 멀티쓰레드 환경에서 동기화를 신경 쓸 필요가 없다.
단점
- 문자열 연산이 많이 일어나는 경우, 더이상 참조되지 않는 객체는 GC(Garbage Collection)에 의해 제거되어야 하기 때문에 성능이 좋지 않다.
- 문자열 연산이 많아질 때, 연산 내부적으로 char 배열을 사용하고, 계속해서 객체를 만드는 오버헤드가 발생하므로 성능이 떨어진다.
StringBuffer와 StringBuilder Class
StringBuffer와 StringBuilderf는 변경 가능하다. 즉 연산을 하면 기존의 클래스의 크기를 변경한 후 문자열을 변셩한다. 그러므로 문자열 연산이 자주 있을때 사용하면 성능이 좋다.
두 개의 클래스가 제공하는 메서드는 동일하다. 두 클래스의 차이점은 동기화 여부이다.
StringBuffer는 각 메서드별로 Synchronized Keyword가 존재하여, 멀티 스레드 환경에서도 동기화를 지원하여 Thread-Safe하다.
StringBuilder는 동기화를 보장하지 않는다. 그러나 싱글 스레드 환경에서 동기화를 고려하지 않기 때문에 StringBuffer에 비해 연산 처리가 빠르다.
그렇기 때문에 Multi-Thread 환경이라면 값 동기화 보장을 위해 StringBuffer를 사용하고, Single-Thread 환경이라면 StringBuilder를 사용하는 것이 좋다.
단순히 성능만 놓고 본다면 연산이 많은 경우, StringBuilder > StringBuffer >>> String 라고 한다.
싸피에서 알고리즘 수업을 진행할 때 교수님이 System.out보다는 StringBuilder를 사용하면 실행속도를 줄일 수 있다고 설명해준적이 있다. 그때는 그 이유를 몰랐었는데 정리 후에는 왜 그런지 알 수 있었다.
참고