티스토리 뷰
Java String #1
String은 Java에서 굉장히 많이 사용되는 변수 타입 중에 하나이며, 또한 관리되어야 할 리소스의 한 종류라고 할 수 있습니다. String은 Primitive 타입과 비슷한 성질을 가지기도 하고, 반면 일종의 class 처럼 동작하기도 합니다. 이런 특이상 성질을 가지고 있고, 잘못 사용하면 service에 잘못된 영향을 줄 수도 있는 String에 대하여 한번 알아보고자 합니다.
- String은 변경 불가능 객체이다 (immutable)
String 객체의 내부 값을 변경하는 것은 불가능하기 때문에, 문자열을 수정하는 모든 mathod는 수정된 새로운 문자열을 반환해 주는 방식으로 동작합니다. String으로 선언된 변수는 해당 변수에 새로운 String을 할당해 주지 않는 이상, 안에 있는 값을 변경할 수 없습니다. Immutable 한 객체는 쓰레드 안전하며, 재사용이 용의하기도 하고 여러가지 이점이 있기 때문에 그렇게 설계된 것으로 생각됩니다.
String은 위와 같은 특징이 있기 때문에 사용시 고민해 보아야할 부분이 있습니다. 만약에 아래와 같은 코드가 있다고 생각해 봅시다.
String str = "a";
for(int i=0;i<1000;i++) {
str += "a"; //str 변수는 항상 새로운 값으로 다시 재할당 됨
}
str 라는 String 변수에 "a" 문자를 정해진 수많은 덧붙이는 로직입니다. str이라는 변수는 처음에는 "a"라는 값을 가지고, 루프를 돌면서 "aa", "aaa", "aaa..." 값으로 점점 변하게 됩니다. 여기서 중요한 부분은 str이라는 변수는 immutable 하기 때문에 항상 새로운 값으로 재할당 되게 됩니다.
내부적으로 동작하는 로직은 다음과 같다고 볼 수 있습니다. (참고로 문자열에 대한 + 연산은 컴파일러에 의해서 자동으로 StringBuilder의 append로 변환됩니다.)
String str = "a";
for(int i=0;i<1000;i++) {
StringBuilder strBuilder = new StringBuilder(str); //strBuilder는 한번 사용되고 버려짐
strBuilder.append("a");
str = strBuilder.toString();
}
루프가 많이 돌면 많이 돌수록 버려지는 StringBuilder 객체는 점점 많아지게 됩니다. GC가 해야할 일이 점점 많아지겠죠.
그래서 많은 수정이 필요한 String은 StringBuilder를 이용하여 명시적으로 처리해 주는 것이 좋습니다. (StringBuffer는 StringBuilder와 동일한 기능을 재공하며, 동기화 처리가 되어 있기 때문에 처리 시간이 좀더 늦습니다)
StringBuilder는 내부적으로 char 배열을 이용하여 문자열을 처리하기 때문에 문자열 수정 시마다 String 객체를 새로 만들어줄 필요가 없습니다.
StringBuilder str = new StringBuilder("a");
for(int i=0;i<1000;i++) {
str.append("a");
}
참고로 단순한 문자열을 + 연산으로 합치는 것과 StringBuilder의 append를 사용하는건 성능상의 차의가 없습니다. (내부적으로 + 연산을 StringBuilder를 이용하여 처리하기 때문)
아래 두가지 로직은 성능상 동일합니다.
String str = "a" + "a" + "a" + "a";
StringBuilder str2 = new StringBuilder();
str2.append("a").append("a").append("a").append("a").append("a")
'개발 > Java' 카테고리의 다른 글
Java Method Overriding (0) | 2016.06.17 |
---|---|
String #2 객체 비교 (0) | 2016.06.03 |
Builder Pattern (0) | 2016.05.06 |
Static factory method (0) | 2016.05.01 |
Spring Value Annotation 사용시 참고 사항 (0) | 2016.04.17 |