String과 String 연산의 최적화

김국민·2025년 3월 14일
0

JAVA

목록 보기
18/21

String class

불변 클래스

String 클래스에 문자열을 저장하기 위해 문자형 배열 참조변수 char[] value를 인스턴스 변수로정의해 놓고 있다
인스턴스 생성시 생성자의 매개변수로 입력받는 문자열은 value에 저장되게 된다
한번 생성된 String 인스턴스가 가지고 있는 문자열은 읽어 올 수 만 있고
변경할 수 없다
그래서 + 같은 연산자를 이용해서 문자열을 결합하는 경우 인스턴스 안의 문자열이 변경되는 것이 아니라 새로운 문자가 담긴 String 인스턴스가 생성된다

문자열 리터럴이란?

자바에서 객체를 생성할 때 일반적으로 new 키워드를 사용하지만 String 클래스는 값을 바로 할당할 수 있다 이것을 문자열 리터럴이라 한다

String str1 = new String("abc");
String str2 = "abc"

이렇게 문자열을 생성하는 두 방식은 실제로 메모리에 저장되는 방식에 차이가 있다

  • new 키워드를 사용하면 힙 메모리 영역에 생성된다
  • 리터럴을 은 상수 풀 에 생성된다

차이점??

  • 동일한 문자열 리터럴을 두개 생성할 경우 각각의 객체는 상수풀에 있는 동일한 문자열을 가르키게 된다
  • new 키워드를 사용해 동일한 문자열 객체를 생성할 경우 힙 메모리에 따로 저장된다. 즉 내용이 같더라고 메모리를 더 차지하게 된다

문자열 연산과 컴파일러 최적화

JDK1.5 이후부터는 String 의 + 연산은 컴파일시에 StringBuilder를 사용하도록 자동변환되어 성능 최적화가 이뤄진다. 그러나 String은 항상 StringBuilder로 변환되지 않는다

///컴파일 전
String str1 = "0" + "1" + "2";
///컴파일 후
String str1 = "012";

String str2 = "";
    str2 += 0;
    str2 += 1;
    str2 += 2;
//컴파일 이 후, 디컴파일 한 소스파일
String str2 = "";
    str2 = (new StringBuilder()).append(s1).append("0").toString();
    str2 = (new StringBuilder()).append(s1).append("1").toString();
    str2 = (new StringBuilder()).append(s1).append("2").toString();

Java Compiler는 문자열 연산 최적화를 어떻게 진행하나요? (String Builder, String...)

String 을 + 연산시에는 리터럴이면 한줄연산인 경우(첫번째 예시) 컴파일러가 연산과정에서 문자열을 결합하는 최적화 후 한번에 상수풀에올린다

두번째 예시의 경우 새로운 String 객체 생성 없이 상수풀에 있는 값들을 append를 통해 연결해준다.

SringBuilder를 사용하는 것과 String을 사용하여 연산하는 것에서 어떠한 큰 차이가 존재할까요?

String 연산시에는 상수풀에 새로운 객체를 생성한다 메모리가 낭비가 된다
StringBuilder는 내부적으로 연산시 새로운 객체를 생성하지 않고 기존 데이터를 변경한다

문자열을 리터럴(string = "abcd")로 할당하는 것과 객체(string = new String("abcd"))로 할당하는 방식의 차이가 무엇인가요?

리터럴 선언은 상수풀에 존재하는 값을 가져와서 쓴다
new 로 만들어진 문자열은 힙 메모리에 새로운 객체를 생성한다

결론

그냥 처음부터 StringBuilder 사용하자

profile
개발지망생

0개의 댓글