개요 #
프로그래밍 언어를 사용할 때 가장 먼저 접하게 되는 클래스 또는 객체이다. 너무 흔한 나머지 String 클래스에 대해 알려고 하지 않는 사람들이 많지만, String 클래스를 사용함에 있어 가장 중요한 개념 두 가지를 정리해 본다.
첫번째, String 클래스의 데이터 처리 #
String insilico = "gen";
위와 같이 insilico라는 String 변수에 "gen"라는 텍스트를 담으면 데이터는 어떻게 저장이 될까? 이렇게 선언 및 초기화를 할 경우 JVM은 RunTime Data Area의 Heap Area에 접근하여 Permanent Area에 String Pool로 등록시킨다. 이과정은 intern() 메서드가 자동호출 되면서 처리되는 과정이다.
String insilico2 = "gen";
위와 같이 insilico2에 똑같은 "gen"라는 텍스트를 선언 및 초기화 하게 되면 기존 String Pool에 "gen"가 저장되어 있는지 검색한 후에 intern() 메서드를 통하여 등록하게 된다. 만약 체크 후 위의 상황처럼 이미등록이 되어 있다면 그대로 사용하게 된다. 변수의 이름은 다 다르지만 모두 한 String Pool의 "gen" 데이터로 동일하다.
String insilico3 = new String("gen")
그렇다면 생성자를 통한 선언은 어떠할까? 이 경우 힙메모리에 "gen"이라는 데이터가 따로 저장이 된다. new 생성자를 사용하는 횟수에 따라 "gen"이 저장된 영역은 많아질 것이다. 같은 텍스트 "gen"이지만 근본적으로 다른 데이터가 된다.
insilico3.intern();
생성자를 통해 선언한 insilico3을 intern()를 통해 실행하면 어떻게 될까? 이경우 String Pool에 등록되며 insilico1 이나 insilico2와 같이 같은 "gen"을 가르키게 된다. 이처럼 같은 String 클래스에 데이터가 담겨도 서로 같거나 다를 수 있다.
두번째, String 클래스과 유사한 클래스 #
String 클래스처럼 문자열을 담는 클래스는 다양하다. 대표적으로 많이 쓰이는 것이 StringBuffer, StringBuilder가 있다.
String Pool에 저장된 데이터는 프로세스가 종료될 때까지 불변한다. 따라서 "plus" 데이터를 추가하면 String Pool의 "gen" 에 글자가 추가 되는 것이 아니라 "genPlus"라는 새로운 데이터가 String Pool에 저장되는 것으로 한번 저장된 String은 불변한다. 반면 StringBuffer와 StringBuilder는 concat등의 문자열 연산을 통해 데이터를 변화시키며, 공간이 부족한 경우 기존의 버퍼크기를 늘리는 등 유연한 동작을 한다. 그렇기 때문에 두 클래스는 String 클래스 보다 연산 속도가 빠르다.
StringBuffer와 StringBuilder의 차이는 StringBuffer는 멀티스레드 환경하 동기화를 지원하고 StringBuilder는 그러하지 못하다는 것이다. 단순 성능만 비교하면 동기화를 진행하지 않는 StringBuilder가 StringBuffer보다 빠르지만 멀티스레드 상황의 유무에 따라 다르다.
사실 JDK 1.5버전 이후 부터 컴파일 단계에서 String 객체를 StringBuilder로 컴파일 되도록 변경되었으나 개발환경이 언제나 JDK 1.5버전일 수는 없으니 반복적인 String 연산작업은 프로그램 성능을 저하시킬 수 있다.
참조 #
http://ooz.co.kr/298
http://egloos.zum.com/deblan2/v/419830
http://egloos.zum.com/deblan2/v/419830