-
[JAVA] String 생성 방법(new / literal)Language/Java 2019. 10. 20. 17:39
String 타입의 변수를 생성할 때는 두 가지 방법이 있습니다.
바로 new 키워드를 사용하는 방법과 리터럴을 이용하는 방법입니다. 비슷해 보이지만 두 방법에는 큰 차이가 있습니다. 바로 저장되는 공간이 다르다는 건데요.
우선, new 키워드를 사용하는 경우는 이전 포스팅에서도 자주 언급했습니다. heap메모리 영역에 실제 데이터가 저장되고 그 메모리를 참조하는 주소 값을 String 변수에 저장하는 것입니다.
따라서 new 키워드를 이용해 String객체를 생성하면 아무리 같은 문자열 데이터를 가지고있다 하더라도 서로 다른 주소 값을 갖게 됩니다.
public class TestString { public static void main(String[] args) { String str1 = new String("Hi"); String str2 = new String("Hi"); System.out.println("str1 과 str2의 주소값 비교 : "+str1==str2); } }
하지만 리터럴을 이용해 생성한 문자열은 다른 결과를 보여줍니다.
public class TestString { public static void main(String[] args) { String str1 = "Hi"; String str2 = "Hi"; System.out.println("str1 과 str2의 주소값 비교 : "+(str1==str2)); } }
보시는 것 처럼 String 변수를 두 개 선언하여 "Hi"라는 문자열을 넣어주었더니 두 변수가 동일한 주소 값을 갖고 있음을 확인할 수 있습니다.
어떻게 이런 결과가 나온걸까요?
String constant pool
리터럴로 문자열을 선언하는 경우 이 데이터는 heap메모리가 아닌 String constant pool, 상수 풀로 저장됩니다.
상수 풀은 heap영역의 permanent area에 생성되어 java 프로그램이 종료될 때까지 유지되는 메모리 영역입니다.
이렇게 되는 이유는 바로 intern() 메소드 때문인데요. intern() 메소드는 String 타입 데이터가 리터럴로 선언될 때 호출되며, 해당 문자열이 상수 풀에 존재하는지 확인합니다. 존재하면 그 주소 값을, 존재하지 않는다면 상수풀에 문자열을 저장한 후 해당 주소 값을 리턴합니다.
그렇다면, new 키워드로 String 객체를 생성할 때 intern() 메소드를 호출하면 어떤 결과가 나타날까요?
public class TestString { public static void main(String[] args) { String str1 = "Hi"; String str2 = new String("Hi").intern(); System.out.println("str1 과 str2의 주소값 비교 : "+(str1==str2)); } }
두 변수의 주소 값이 동일한 것을 확인할 수 있습니다.
new 키워드로 객체를 생성해도 intern() 메소드가 실행되면서 상수 풀에 "Hi"라는 문자열을 갖는 데이터가 있는지 확인하고, 상수풀에 있는 데이터를 참조하게 되는 것입니다. (heap메모리의 객체를 참조하지 않음)
'Language > Java' 카테고리의 다른 글
[JAVA] 다형성(Polymorphism) (0) 2019.11.09 [JAVA] 추상클래스와 인터페이스 (0) 2019.11.09 [JAVA] String/String Builder/String Buffer 비교 (0) 2019.10.20 [JAVA] Static이란? / Static변수 및 메소드 호출 (0) 2019.10.06 [JAVA] Static이란? / Garbage Collector (0) 2019.10.06