2023. 3. 5. 23:39ㆍ자바
자바의 문자열
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를 사용하는 것이 훨씬 더 효율적이다.
'자바' 카테고리의 다른 글
단일 책임 원칙, 하나의 객체는 하나의 책임을 갖는다. (0) | 2023.03.14 |
---|---|
아이템 68, 항상 표준 명명 규칙을 따라야한다. (0) | 2023.03.08 |
아이템 15, 클래스와 멤버의 접근 권한을 최소화하라 (0) | 2023.03.02 |
자바, 객체야~ 일해라! (0) | 2023.02.27 |
이펙티브 자바, 의존 객체 추입 (0) | 2023.02.26 |