new String();과 String str = "";의 차이점

SINHOLEE·2020년 6월 25일
0

1.한마디 정리

  • new String()은 새로운 객체를 만드는 것으로 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 poolheap 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 poolasd가 있어서 str1과 str2는 서로 같은 asd 를 참조하는 것일까?

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

2. 비슷한 문제

아래의 경우 몇 개의 새로운 데이터가 생길까? (How many Strings are getting Created in the String Pool?)

String str = new String("Cat");
  • 답은 엄밀히 따지면 1개 혹은 2개이다. 만약 "Cat" 이라는 스트링 값이 있었다면, 그냥 바로 new 오퍼런트로 인해 str이라는 인스턴스를 생성하기 때문에 1개가 생성된다고 한다. 반면, "Cat"이라는 스트링이 string constant pool에 없었다면 우선 해당 풀에 "Cat"이라는 스트링을 생성하고, 그 다음 str 인스턴스를 생성하여 총 두 개의 데이터가 생성된다.
  • 2020.06.26 아래 테스트 결과 new로 생성한 새로운 인스턴스에 해당하는 스트링은 string constant pool에 존재하지 않고, intern함수를 실행하거나, 새로운 스트링을 =로 할당할 때 비로소 constant pool에 저장한다.

3. 테스트

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);
    }
}

4. 참조

profile
엔지니어로 거듭나기

0개의 댓글