다음의 두 방식이 모두 가능합니다.
String s = "hello world"; // literal 선언
String s2 = new String("hello world"); // 객체로 선언
두 방식 모두 JVM의 heap에 저장되지만 literal
로 선언한 문자는 heap 중에서도 String Constant Pool
에 저장됩니다.
literal 방법으로 문자열을 생성할 때에는 String Constant Pool에 해당 문자열이 존재하는지 확인하고, 해당 문자열이 존재한다면 새로 생성하지 않고 그 객체를 참조합니다.
// String Constant Pool에 hello world의 객체가 생성됩니다.
String s = "hello world";
// String Constant Pool에 hello world가 존재하기 때문에 새로 만들지 않고 그 객체를 참조합니다.
String s2 = "hello world";
// 그렇기 때문에 주소값을 비교하는 ==연산의 결과는 true가 나옵니다.
System.out.println(s==s2); // true
new
키워드를 사용하면 무조건 새로운 객체가 생성됩니다. 이때 String Constant Pool이 아닌 일반적인 heap 영역에 생성됩니다. String s = "hello world";
String s2 = new String("hello world");
String s3 = new String("hello world");
// literal과 new는 다른 객체를 참조하고 있습니다.
System.out.println(s == s2);//false
// new끼리도 서로 다른 객체를 참조하고 있습니다.
System.out.println(s2 == s3);//false
String s = "hello world";
String s2 = new String("hello world");
// literal과 new는 다른 객체를 참조하고 있습니다.
System.out.println(s == s2);//false
// s2를 String Constant Pool에 저장합니다.
// 이미 Hello world라는 값이 String Constant Pool에 있기 때문에 해당 주소를 참조합니다.
s2 = s2.intern();
//이제 s와 s2는 같은 객체를 참조하고 있습니다.
System.out.println(s == s2);//true
이미지 출처: https://dydtjr1128.github.io/java/2019/04/23/JAVA-String.html