17.String 클래스
String을 선언하는 두 가지 방법
자바는 문자열을 사용할 수 있도롱 String 클래스를 제공합니다. 문자열은 프로그램을 구현할 때 많이 활용합니다. String을 사용할 때 문자열을 생성자의 매개변수로 하여 생성하는 방식과 이미 생성된 물자열 상수를 가리키는 방식이 있습니다.
String을 생성자로 생성했을 때의 주소 값과 문자열 상수를 바로 가리킬 때의 주소 값을 비교합니다. 문자열 상수를 바로 가리키는 경우에는 주소 값이 같음을 알 수 있습니다.
String 클래스의 final char[] 변수
다른 프로그래밍 언어는 문자열을 구현할 때 일반적으로 char[] 배열을 사용삽니다. 자바는 String 클래스를 제공해 char[] 배열을 직접 구현하지 않고도 편리하게 문자열을 사용할 수 있습니다.
String 클래스 구현내용을 보면 private final char value[]라고 선언된 char형 배열이 있습니다.
String s = new String("abc")라고 쓰면 abc는 String 클래스의 value 변수에 저장됩니다. 그런데 이 변수는 final 로 선언 되어 있습니다. final은 문자열을 변경할 수 없다는 뜻입니다. 따라서 한 번 생성된 문자열은 변경되지 않습니다. 이런 문자열의 특징을 '문자열은 불변(immutable)한다' 라고 합니다. 그래서 두 개의 문자열을 연결하게 되면 둘 중 하나의 문자열이 변경되는 것이 아니라 두 문자열이 연결된 새로운 문자열이 생성됩니다.
StringBuffer와 StringBuilder 클래스 활용
프로그램을 만들다 보면 문자열을 변경하거나 연결해야 할 때가 많습니다. 그런데 String클래스는 한번 생성되면 그 내부의 문자열이 변경되지 않기 때문에 String 클래스를 사용하여 문자열을 계속 연결하거나 변경하는 프로그램을 작성하면 메모리가 많이 낭비됩니다. 이 문제를 해결하는 것이 바로 StringBuffer와 StringBuilder 클래스입니다.
StringBuffer와 StringBuilder는 내부에 변경 가능한(final이 아닌) char[]를 변수로 가지고 있습니다. 이 두 클래스를 사용하여 문자열을 연결하면 기존에 사용하던 char[] 배열이 확장되므로 추가 메모리를 사용하지 않습니다. 따라서 문자열을 연결하거나 변경할 경우 두 클래스 중 하나를 사용하면 됩니다. 두 클래스의 차이는 여러작업(스레드)이 동시에 문자열을 변경하려 할 떄 문자열이 안전하게 변경되도록 보장해 주는가 그렇지 않은가의 차이입니다.
StringBuffer 클래스는 문자열이 안저낳게 변경되도록 보장하지만, StringBuilder 클래스는 보장되지 않습니다.
프로그램에서 따로 스레드를 생성하는 멀티스레드 프로그램이 아니라면 StringBuilder를 사용하는 것이 실행 속도가 좀 더 빠릅니다.
5행에서 생성한 "Java" 문자열에 여러 문자열을 추가해야 하는 경우에 8행에서처럼 일단 StringBuilder 클래스를 생성하고 여기에 문자열을 추가 (append)합니다. 그러면 Append()메소드가 실행 될 때마다 메모리가 새로 생성되는 것이 아니라, 하나의 메모리에 계속 연결되는 것을 해시 코드 값을 통해 알 수 있습니다. 연산 전 메모리 주소와 연산 후 메모리 주소가 같기 때문이지요. 문자열을 변경한 후에 buffer에 toString() 메소드를 호출하면 다시 문자열로 반환할 수 있습니다.