만족은 하되 안주하지는 말자

기록해야 기억한다

프로그래밍/JAVA

[Java] 문자열 붙이기에 반드시 StringBuilder 를 안해도 된다

D36choi 2021. 6. 5. 15:07
728x90

서론

개발을 하다가 멘토님께 알게 된 사실을 정리한다.

사실 나는 문자열 붙이기를 할 때, '+' 를 활용하면 메모리 낭비가 너무 커질 수 있어 지양해야한다는 생각을 가지고 코드를 작성해왔다.

이 주제는 상당히 오래전부터 자바를 공부하는 우리 컴공생들에게 (면접질문 등으로) 자주 논의되던 이야기였다.

문자열 붙이기에 '+' 를 이용하지말아야한다는 근거

String 객체는 불변 객체이다. 즉 한번 객체가 생성되면 그 객체 내용을 변경하는건 불가능하다.

그래서 우리가 한 문자열을 다른 문자열과 합치게 되면 기존 문자열의 내용이 변하는게 아니라 새로운 문자열이 생성된다.

그리고 이제 참조되지않는 (아래 그림의 경우 "Hello") 문자열은 더이상 어느 코드에서도 참조되지않으므로 GC(Garbage Collector)에 보내져 소멸을 기다린다.

힙 영역을 차지하고 있는 문자열의 주소를 스택의 str 이 가리킨다.

만약 문자열을 백만개 합친다면?

문자열을 백만개 합친다면 쓸모없는 문자열이 100만 - 1 개 만큼 생겨나게 될 것이고 이는 컴퓨터 자원의 당연히 큰 낭비다.

그래서 StringBuilder 를 써야 한다

StringBuilder 는 가변적인 문자열 객체처럼 동작하고, append method 는 문자열 붙이기(concatenation)를 할때마다 문자열이 새로 생겨나는걸 막아준다.

public static void main(String [] args) {
    // '+'
    String str = "Hello " + "World";
    // StringBuilder
    StringBuilder sb = new StringBuilder();
    sb.append("Hello ");
    sb.append("World");

}

그래서 나는 당연히도, ㅈ간단한 문자열 합치기에도 StringBuilder 를 이용해서 해왔다.

그러나 그러지 않아도 된다

하지만 JDK1.5 출시 이후부터 (출시일은 2004년 9월 4일이다...)
자바 컴파일러는 간단한 형식의 '+' 를 이용한 문자열 합치기를 자동적으로 StringBuilder 를 활용한 문자열 붙이기로 변환하기 때문에 '+' 를 사용해도 성능 상의 이슈가 발생하지 않는다!

결론

*코드 가독성을 위해 그냥 '+' 로 문자열을 합치자. 단 loop 내 문자열 합치기는 예외 *

그러나 예외도 존재한다. 만약 loop 안에서 문자열을 합쳐야하는 경우에는 java compiler 가 StringBuilder 로 변환하지 않는다.
즉 이런 경우에는 개발자가 명시적으로 StringBuilder 를 사용해주는 것이 좋다.

 

 

나는 이 사실을 모르고, 2004년도부터 개선되어온 부분에 대해서 알지 못한채 '+' 를 사용한 문자열 붙이기를 죄악시했다.
오히려 기능상의 차이가 없을 때에도 StringBuilder 를 사용해 문자열을 붙이게 되면 오히려 코드가 길어져 가독성이 떨어지지 않을까 생각한다.
큰 걸 하나 배운 것 같다.

https://dzone.com/articles/string-concatenation-performacne-improvement-in-ja