[Java] 문자열 + 결합 내부 동작 방법 분석

호성·2022년 1월 31일
0
post-thumbnail
String str = "java" + 8 + " study";

먼저 이렇게 문자열 대상으로 + 연산이 가능한 이유는 자바 컴파일러가 + 연산을 기존에 구현되어있던 방법으로 변환해주기 때문이다.

그렇다면 구체적으로 어떤 방법으로 변환해주는 걸까?

과거 JDK 버전에서는 이를,

String str = "java".concat(String.valueOf(8)).concat(" study");

위와 같이 변환해줬다. 위 방식에는 아래와 같은 문제점이 있다.

1. 위 예시에서는 숫자 8과 같이 기존에 String이 아닌 자료형을 매번 String.valueOf() 메소드를 호출하여 변환하게 된다.

2. String.concat() 메소드는 concatenate 동작 수행 후 매번 새로운 String 인스턴스를 반환한다.

  • 결국 위 예시에서 마지막으로 생성되는 인스턴스를 제외하고, 중간에 생성되는 String 인스턴스는 사용하지 않는(Unreachable Instance) 인스턴스이다. => 쓸데없이 가비지 컬렉션이 작동할 것이다.

하지만 JDK1.5 버전 이후 부터 위 방식의 문제점을 해결하고자 + 연산에 대한 내부 동작이 변경되었다.

StringBuilder의 등장

StringBuilder는 내부적으로 문자열을 저장하기 위한 메모리 공간을 지니는데, String과 달리 해당 공간에 대해 문자를 추가하거나 삭제하는 것이 가능하다.

미리 메모리 공간이 정해져있으며, 필요 시 알아서 공간을 늘리는 작업을 하는데 해당 작업이 자원의 소모가 많은 작업이다.

문자열 + 연산이 컴파일러에 의해 StringBuilder를 사용하는 방식으로 변경되었는데 그 방법은 아래와 같다.

String str = (new StringBuilder("java").append(8).append(" study")).toString();

1. 마지막에 딱 한 번의 toString()의 호출로 String.concat()의 계속해서 일어나는 타입 변환 문제를 해결했다.

2. 이 때, StringBuilder.append() 의 수행 결과는 새로운 인스턴스가 아니라 기존 인스턴스에 append() 안에 있는 매개변수를 붙인 것이다. 따라서 새로운 인스턴스를 생성하지 않는다.

결과적으로 + 연산의 내부 구현 방식이 변경되면서 기존 문제점이 해결됐다고 볼 수 있는데,

그럼에도 불구하고 + 연산이 StringBuilder로 변환되는 과정이 있으므로 StringBuilder를 직접적으로 사용하는 것 보다는 성능이 느릴 것이다.

따라서 문자열 결합을 엄청나게 많이 수행해야 한다면 StringBuilder를 직접 사용하여 append => toString()하는 것이 나을 것이다. 하지만 그렇지 않다면..내부 동작이 개선된 + 연산을 편하게 사용하면 되지 않을까 싶다.

끗.

profile
스프링 깎는 노인

0개의 댓글