<Java> String 클래스 초기화와 String Constant Pool

자바에서 String을 초기화하는 두가지 방식

String str1 = "abc"; //문자열 리터럴 "abc"의 주소가 str1에 저장됨
String str2 = "abc"; //문자열 리터럴 "abc"의 주소가 str2에 저장됨
String str3 = new String("abc"); //새로운 String 인스턴스 생성
String str4 = new String("abc"); //새로운 String 인스턴스 생성
  • str1,st2가 문자열 Literal을 지정하는 방법으로 초기화 하였고, str3,str4가 String 클래스의 생성자를 사용하는 방법으로 초기화 되었다.
  • 위 그림처럼, str1과 str2는 같은 객체를 참조하고 있지만, str3와 str4는 다른 객체를 참조하고 있다.
  • str1과 str2가 참조하는 객체가 String Constant Pool에 선언되어 있다.

문자열 Literal

  • 자바 소스파일에 포함된 모든 문자열 리터럴은 컴파일 시에 클래스 파일에 저장된다.(바이트 코드)
  • 이때 같은 내용의 문자열 리터럴은 한번만 저장된다.
  • 문자열 리터럴도 String 인스턴스로 생성된다.

String Constant Pool이란?

  • Heap 영역에서 String 객체를 별도로 관리하는 장소이다.
  • 먼저 문자열 리터럴 방식으로 String을 초기화 할 경우, String Constant Pool에 해당 문자열이 존재하는지 여부를 체크하고 있는경우 해당 리터럴의 주소를 할당하고 없는경우엔 해당 문자열을 값을 가지는 객체를 String Constant Pool에 생성한다.
  • 위의 과정을 수행하는 메서드가 String 클래스 내의 intern()이다. 해당 메서드는 String 인스턴스의 주소값을 반환한다.
  • String 생성자를 사용해서 인스턴스를 만들어서 초기화 할 경우, String Constant Pool 바깥 영역에 객체를 생성한다.(Heap 영역 내이지만)
  • 아래의 코드를 보면 intern() 의 동작 방식을 이해 할 수 있다.
public class Intern {

    public static void main(String[] args) {
        String literal = "brido";
        String object = new String("brido");
        String intern = object.intern();

        System.out.println(literal == object); // false
        System.out.println(literal.equals(object)); // true
        System.out.println(literal == intern); // true
		/* 
			아래 라인에서 true가 리턴되는 이유는 intern()은 "brido"를 
			String Constant Pool에서 검색하고, 존재하는 리터럴이기 때문에
			해당 주솟값을 리턴하기 때문이다.
		*/
        System.out.println(literal.equals(intern)); // true
    }

}