티스토리 뷰
[Java] String, StringBuffer, StringBuilder 차이
Namhyun Sung 2020. 5. 26. 16:521. String, String에서 + 연산을 하면 안되는 이유
Java를 사용하면서 자주 사용하는 String
은 Immutable
특성을 가지고 있습니다. Immutable
이란 변경할 수 없는, 불변이라는 뜻으로 String
의 값은 한번 생성이 되면 할당된 공간이 변하지 않는다는 특성이 있습니다.
그러면 아래와 같이 + 연산을 했을 때, 합쳐지는 것은 어떻게 처리 되는 것일까요?
String str = "a";
str += "b";
위 코드 처럼 + 연산을 하면 메모리를 할당받아 새로운 String 클래스 객체를 만들어서 문자열을 나타냅니다. 그리고 이전에 참조하던 "a"는 쓰레기가 되고 나중에 가비지 컬렉터에 의해 제거됩니다. 이러한 이유 때문에, 시간과 메모리가 많이 소모됩니다. 연산을 많이 할수록 성능 차이는 더 심해지게 됩니다.
이러한 문제를 해결하기 위해 Java 1.5
버전부터는 String을 + 연산 했을 때, StringBuilder
가 사용되도록 변경 되었습니다.
String str = "a";
for(int i=0; i<100;i++) {
str += "b";
}
실제로 위의 코드의 디컴파일해보면 아래처럼 StringBuilder
를 사용하고 있습니다.
String str = "a";
for(int i = 0; i < 100; i++)
s = (new StringBuilder()).append(s).append("b").toString();
그런데 자세히 보면 new StringBuilder
가 반복문안에서 생성됩니다.
반복문 안에서 문자열을 더하는 연산을 한다면 StringBuilder
가 반복문 횟수만큼 생성되기 때문에 StringBuilder
나 StringBuffer
를 사용하는 것보다 느릴 수 밖에 없습니다.
때문에 반복문 안에서 문자열 덧셈 연산을 하여 문자열의 길이 변경할 때 String
이 매우 불리한 것을 알 수 있습니다.
2. StringBuffer, StringBuilder가 String 보다 문자열 연산에서 좋은 성능을 가지는 이유
StringBuffer
, StringBuilder
에서도 마찬가지로 문자열 복사를 하긴 하지만 가변 크기 배열을 이용해서 필요한 경우에만 문자열을 복사합니다.
16의 공간을 갖고있고 그 공간을 넘어서는 글자가 올경우 남아있는공간을 두배 늘리고 기존 문자열을 복사하는 형태로 동작합니다.
따라서 문자열을 더하더라도 매번 문자열을 복사하지 않아서 성능을 높일 수 있다.
3. StringBuffer, StringBuilder의 차이점
StringBuffer
, StringBuilder
의 차이점은 synchronized
키워드 지원 여부입니다.
StringBuffer
는 synchronized
키워드를 지원하기 때문에(thread-safe) 멀티쓰레드 환경에서 안전합니다.
그에반해 StringBuilder
는 synchronized
키워드를 지원하지 않기때문에 단일쓰레드 환경에서 사용해야 안전합니다.
4. 그럼 String은 언제 사용하는가?
String
은 immutable
속성을 가짐으로써 안전하다고 했습니다. 값이 변경되지 않기 때문에 여러 스레드가 데이터를 공유하더라도 동기화를 신경쓸 필요가 없이 안정성이 유지
되는 장점이 있습니다.
그리고 StringBuffer
, StringBuilder
클래스에서도 String 클래스를 이용합니다. toString() 메소드의 경우 StringBuffer, StringBuilder의 toString()가 호출되면 해당 문자열에 대한 String 객체를 생성해서 반환합니다.
따라서 연산이 적게 사용되고, 문자열 값의 수정 없이 읽기가 많은 경우에는 String
클래스의 사용이 더 적절합니다.
5. 참고
'Programming > Java&Spring' 카테고리의 다른 글
[Java] final 키워드 (0) | 2020.05.29 |
---|---|
Springboot jar 패키징 후 실행 방법 (0) | 2019.11.27 |
Maven과 Gradle (0) | 2019.11.23 |
[Spring] 생성자 주입을 사용해야 하는 이유, 필드인젝션이 안좋은 이유(+Lombok를 사용한 생성자 주입 방법) (0) | 2019.11.20 |
Lombok 사용 시 @JsonIgnore 동작안하는 문제 해결 (0) | 2019.11.18 |
- Total
- Today
- Yesterday
- DI
- 애플리케이션컨텍스트
- springboot
- JsonIgnore
- IoC
- 템플릿
- java
- JsonProperty
- 스프링
- jar 실행
- Tomcat
- EmbededTomcat
- 빌드도구
- 연동
- 413
- 토비의스프링
- stringbuffer
- gradle
- apache
- lombok
- 스프링프레임워크
- mod_jk
- 자바
- Spring
- shellscript
- StringBuilder
- AOP
- final
- 쉘스크립트
- 빈팩토리
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |