자바의 문자열

2023. 3. 5. 23:39자바

728x90
반응형

자바의 문자열

String 생성 방법

일반적으로 리터럴로 String을 생성하거나 new 키워드로 객체를 생성하거나 intern()을 사용하는 방식이 있다.

final String a = "a";
final String b = new String("a");
final String c = new String("a").intern();

리터럴을 사용해 String 객체를 생성하는 경우에는 새로운 String 객체를 생성하지 않는다.

반면에 new String을 하게 되면 새로운 객체를 만들게 된다. 따라서 다음의 결과가 발생한다.

System.out.println(a == b); // false

하지만 intern()을 사용하는 경우에는 String pool에 값이 없다면 이를 생성하고, 그 값을 가리키는 식으로 동작한다. 만약 값이 있다면 이를 생성하지 않고 그 값을 가리키는 식으로 동작한다.

따라서 다음과 같은 결과가 발생한다.

System.out.println(a == c); // true

하지만 일반적으로 우리는 intern()이라는 함수를 사용하지 않는다.

사실 이는 과거 자바 버전에서 사용했던 함수이다.

자바 8버전 이전에서는 + 연산자를 사용해서 문자열 결합을 하게 되면 StringBuilder가 사용됐다. 하지만 이는 문자열을 결합할 때마다 매번 StringBuilder 객체를 생성한다는 단점이 발생했다. 이에 따라 그 이후 버전에서는 정적 메서드인 makeConcatFactory를 사용해 문자열을 더해주는 작업을 했다.

만약 final 키워드를 사용해 불변 String으로 만들어준다면 + 연산자를 사용하더라도 jvm이 최적화를 해줘서 결합된 문자열을 리터럴로 선언한 것과 동일한 성능을 보인다.

final String a = "a";
final String b = "b";
final String c = "c";

System.out.println(a + b + c) // LCD "abc"

그렇다면 StringBuilder를 사용하지 않아도 되는 것인가?

문자열을 반복적으로 더하는 경우에는 StringBuilder가 사용하는 것이 좋다.

String s = "a";
final StringBuilder sb = new StringBuilder();

for (int i = 0; i < 1000; i++) {
	sb.append(i); // StringBuilder 객체가 하나만 생겨난다.
}

만약에 이때 +를 사용해 문자열을 결합한다면 String 객체가 String pool에 매번 생겨나게 된다.

String s = "a";

for (int i = 0; i < 1000; i++) {
	s += i // String을 매번 생성한다.
}

따라서 위와 같이 StringBuilder를 사용하는 것이 훨씬 더 효율적이다.

728x90
반응형