본문 바로가기

JAVA

문자열 리터럴 할당 VS new String()

요약

혹시 여러분은 String str1 = "abc"와 String str2 = new String("abc")의 차이에 대해 아시나요??


혹시 이렇게 답변하실수 있다면 이 글을 읽지 않으셔도 되고, 모르신다면 저랑 함께 이 둘의 차이에 대해 알아보겠습니다!

문자열을 리터럴과 객체로 할당하는 방식의 차이는 메모리 할당 방식과 성능에 있습니다.
자바 소스 코드에 포함된 모든 문자열 리터럴은 컴파일 시에 클래스 파일에 저장됩니다. 이후 클래스 파일이 클래스 로더에 의해 메모리에 올라갈때, 클래스 파일의 리터럴들이 JVM 내에 있는 String constant Pool에 올라가게 됩니다.
이때 같은 문자열 리터럴이 여러번 사용될 경우, 중복을 방지하기 위해 하나의 인스턴스를 공유하게 됩니다. 이러한 리터럴 방식은 중복을 최소화하고 메모리를 효율적으로 사용할 수 있습니다.
문자열 객체 생성 시에는 힙 영역에 새로운 객체가 생성됩니다. 이 경우에는 같은 문자열이라도 매번 새로운 객체를 생성하게 되어 메모리 사용에 비효율적입니다.

String 클래스

자바에서 String 클래스는 문자열을 저장하기 위해 char[](문자형 배열)참조 변수인 value를 인스턴스 변수로 정의해놓고 있습니다.

인스턴스 생성 시 생성자의 매개변수로 입력받은 문자열을 인스턴스변수(value)에 문자형 배열(char[])로 저장합니다.

이러한 자바의 String을 불변 객체라고 합니다. 즉 객체 생성 이후 내부의 상태가 변하지 않는 객체라는 뜻입니다.
이때 String이 변경 불가능하다는 것은 객체 자체는 변경할 수 없지만 객체에 대한 참조는 변경할 수 있습니다.

그러면 자바에서는 왜 String을 불변 객체로 만들었을까요?

String str1 = "madplay";
String str2 = "madplay";

System.out.println("str == str2 : " + (str1==str2)); // true

위의 코드 과정을 분석해보면 우선 문자열 str1에 해당하는 것을 String Constant Pool에서 찾습니다. 없다면 상수풀에 등록하고 해당하는 레퍼런스 값을 반환하게 됩니다.

 

이후 str2는 따로 객체를 생성할 필요 없이, 상수풀 내의 madplay의 레퍼런스(주소)만을 가리키면 됩니다.

즉 불변성을 가진 문자열은 동일한 문자열을 중복 저장하지 않고 String Pool에서 관리할 수 있어, 메모리 사용이 최적화되며 성능이 향상되는 것입니다!

 

이러한 String이 불변해야 하는 더 자세한 이유는 이 블로그를 참조해주세요!

https://starkying.tistory.com/entry/why-java-string-is-immutable


자바에서 String 선언방법

자바에서는 new 연산자 방식리터럴 방식으로 String을 선언할 수 있습니다. 이 둘은 어떠한 차이가 있을까요?

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

System.out.println("str1==str2 : " + (str1==str2)); //false

이 둘의 차이는 실제 메모리에 할당되는 영역에 차이가 있습니다!

 

new 연산자를 통해 문자열 객체를 생성하는 경우, 메모리의 Heap 영역에 할당되고, 두번째 방법인 리터럴 방식으로 생성시 String Constant Pool이라는 상수풀 영역에 할당됩니다.

 

그래서 할당하는 메모리 주소가 다르기 때문에 주소값이 달라 false가 나오는 것입니다!

이때 값만을 비교하는 equals() 메서드로는 당연히 true가 나오겠죠??


참고

자바의 정석
https://starkying.tistory.com/entry/why-java-string-is-immutable
https://velog.io/@mooh2jj/%EC%9E%90%EB%B0%94%EC%9D%98-String-%EC%83%9D%EC%84%B1-%EB%B0%A9%EC%8B%9D-%EB%A6%AC%ED%84%B0%EB%9F%B4%EB%B0%A9%EC%8B%9D-vs-new-%EC%97%B0%EC%82%B0%EC%9E%90-%EB%B0%A9%EC%8B%9D