Java에서는 String을 생성하는 방법
Java에서는 String을 생성하는 방법은 2가지가 있다.
- String literal : 큰 따옴표(””)를 이용하는 것
- new 연산자를 사용하는 것
테스트 코드
@DisplayName("String literal로 생성한 두 객체는 주소값이 같다.")
@Test
void stringLiteral() {
String a = "aaa";
String b = "aaa";
assertThat(str1).isSameAs(str2);
}
@DisplayName("new 연산자로 생성한 두 객체는 주소값이 같지 않다.")
@Test
void stringLiteral() {
String c = new String("aaa");
String d = new String("aaa");
assertThat(c).isNotSameAs(d);
}
Java에서는 String을 저장하는 곳
- Java에서는 String을 저장하는데 2곳의 메모리를 사용할 수 있다.
new String(”aaa”)
으로 실행한 c, d의 경우 일반 객체들과 마찬가지로 Heap 영역에 생성된다.
- 리터럴을 이용하여 생성한 경우인 a, b의 경우 String Constant Pool에 생성되어 있는 String 객체들을 가리킨다.
String Interning
- Java에서는 String은 일반적인 Heap에 저장할 수 있고 또한 별도의 String Constant Pool이라는 공간을 제공하고 있다.
- String Constant Pool에 저장하고 사용하는 것을 String Interning이라고 한다.
- 이렇게 String Interning에 저장된 값은 불변성(Immutability)을 가지게된다.
- 불변성을 가진다는 의미는 값은 변함이 없으며 동일한 String 값을 가지고 있다면 같은 곳을 가리킨다는 의미인다.
- String Interning은 아래의 흐름으로 값을 찾습니다.
- String의 값이 String Constants Pool에 있는지 찾는다.
- 있다면 바로 반환한다.
- 없다면 StringConstants Pool에 해당 값을 할당한다.
- 반환
- 흐름을 보면 String Pool을 이용하기 때문에 같은 값에 대해서는 새로운 메모리에 할당 없이 재사용 가능하다는 장점을 가지고 있다는 것을 알 수 있다.
리터럴을 이용한 String 생성과 new String()을 이용한 String 생성의 차이
- 가장 큰 차이점은 객체가 생성되는 영역이다.
new String()
을 이용한 String 생성은 Heap 영역에 생성된다.
- 리터럴을 이용한 String 생성은 String Constant Pool 영역에 생성된다.
- String Constant Pool도 엄밀히 따지면 Heap 내부에 존재한다.
결론
- String 객체를 new 연산자로 생성하면, 같은 값이라 할지라도 Heap 영역에 매번 새로운 객체가 생성된다. 따라서 String이 갖는 불변성이라는 장점을 누리지 못한다.
- 결국 메모리를 효율적으로 사용하기 위해서는 항상 String literal(큰 따옴표)로 String을 생성하는 것이 좋겠다.
참조
https://sabarada.tistory.com/137
https://starkying.tistory.com/entry/what-is-java-string-pool
https://dololak.tistory.com/718