heap area
에 저장이 되고, String str = ""; 처럼 리터럴을 이용한 변수 할당은,string constant pool
영역에 저장되기 때문에 서로 잠조하고 있는 레퍼런스 주소가 다르다. 즉.String str1 = new String(""); // 44444
String str2 = ""; // 123422
str1 == str2 // 서로 다른 레퍼런스 참조 false
str1.equals(str2) // 서로 같은 값 ture
String str3 = "apple"; // 123123123
String str4 = "apple"; // 123123123
str3 == str4
string constant pool
은 heap area
에 포함되어 있는 공간이다.
As the name suggests, String Pool in java is a pool of Strings stored in Java Heap Memory. We know that String is a special class in java and we can create String objects using a new operator as well as providing values in double-quotes.
리터럴로 스트링을 생성한다면, 내부적으로 intern()
이라는 메소드가 실행되면서, string constant pool
를 한번 훑고 기존에 존재하는 string값이 있으면, 그 값의 레퍼런스 주소를 할당받고, 없으면 새로 생성한 뒤 그 주소를 받도록 한다.
궁금한 점 string constant pool
에 asd
가 있어서 str1과 str2는 서로 같은 asd
를 참조하는 것일까?
String str1 = new String("asd");
String str2 = new String("asd");
아래의 경우 몇 개의 새로운 데이터가 생길까? (How many Strings are getting Created in the String Pool?)
String str = new String("Cat");
string constant pool
에 없었다면 우선 해당 풀에 "Cat"이라는 스트링을 생성하고, 그 다음 str 인스턴스를 생성하여 총 두 개의 데이터가 생성된다.string constant pool
에 존재하지 않고, intern
함수를 실행하거나, 새로운 스트링을 =
로 할당할 때 비로소 constant pool
에 저장한다.import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import org.junit.jupiter.api.Test;
public class StringTest {
@Test
public void testNewInstanceFirst() {
System.out.println("testNewInstanceFirst");
// new
String a = new String("ssafy");
String b = new String("ssafy");
int a_addr = System.identityHashCode(a);
int b_addr = System.identityHashCode(b);
System.out.println("a : " + a_addr);
System.out.println("b : " + b_addr);
System.out.println();
assertNotEquals(a_addr, b_addr);
// leteral
String c = "ssafy";
String d = "ssafy";
int c_addr = System.identityHashCode(c);
int d_addr = System.identityHashCode(d);
System.out.println("c : " + c_addr);
System.out.println("d : " + d_addr);
System.out.println();
assertEquals(c_addr, d_addr);
// intern
String e = b.intern();
System.out.println("e : " + System.identityHashCode(e));
}
@Test
public void testLiteralFirst() {
System.out.println("testLiteralFirst");
// literal
String c = "ssafy";
String d = "ssafy";
int c_addr = System.identityHashCode(c);
int d_addr = System.identityHashCode(d);
System.out.println("c : " + c_addr);
System.out.println("d : " + d_addr);
System.out.println();
assertEquals(c_addr, d_addr);
// new
String a = new String("ssafy");
String b = new String("ssafy");
int a_addr = System.identityHashCode(a);
int b_addr = System.identityHashCode(b);
System.out.println("a : " + a_addr);
System.out.println("b : " + b_addr);
System.out.println();
// fail test
assertEquals(a_addr, d_addr);
}
@Test
public void testInternFirst() {
System.out.println("testInternFirst");
// new and intern
String a = new String("ssafy");
String b = a.intern();
int a_addr = System.identityHashCode(a);
int b_addr = System.identityHashCode(b);
System.out.println("a : " + a_addr);
System.out.println("b : " + b_addr);
System.out.println();
assertNotEquals(a_addr, b_addr);
// literal
String c = "ssafy";
int c_addr = System.identityHashCode(c);
System.out.println("c : " + System.identityHashCode(c));
assertEquals(b_addr, c_addr);
}
@Test
public void testStringPlus() {
String a = "ssafy";
String b = "ssa" + "fy";
int a_addr = System.identityHashCode(a);
int b_addr = System.identityHashCode(b);
System.out.println("a : " + a_addr);
System.out.println("b : " + b_addr);
assertEquals(a_addr, b_addr);
}
}