String

ymk·2023년 6월 15일
0
post-thumbnail

🚫 변경 불가능한(immutable) 클래스

String 클래스에는 문자열을 저장하기 위해서 문자형 배열 참조변수(char[]) value를 인스턴스 변수로 정의해놓고 있다. 인스턴스 생성 시 생성자의 매개변수로 입력받는 문자열은 이 인스턴스 변수(value)에 문자형 배열(char[])로 저장된다.

그런데 한번 생성된 String 인스턴스가 가지고 있는 문자열은 읽어 올 수만 있고, 변경은 불가능하다.

String a = "a";
String b = "b";
a = a + b;

여기서 '+' 연산을 이용하여 문자열을 결합하는 경우 인스턴스의 문자열이 바뀌는 것이 아닌 새로운 문자열 "ab"이 담긴 String 인스턴스가 생성되는 것이고 변수 a는 그 새로운 인스턴스를 가르키게 되는 것이다. 그래서 이렇게 '+' 연산을 계속하면 메모리 공간을 차지하게 되므로 횟수를 줄이는 것이 좋다.


🔨 Literal vs 객체 생성

변수의 초기값은 코드에서 직접 입력하는 경우가 많은데, 소스 코드 내에서 직접 입력된 값을 리터럴(Literal) 이라고 부른다.
예를 들면 이렇다.

int a = 10;
char b = 't';
String c = "Hello";

자바 소스 파일에 포함된 모든 문자열 리터럴은 컴파일 시에 클래스 파일(.class)에 저장된다. 이때 같은 내용의 문자열은 한번만 저장된다. 문자열 리터럴도 결국 String 인스턴스이며 한번 생성하면 내용을 변경할 수 없으니 하나의 인스턴스를 공유하면 되기 때문이다.
클래스 파일에는 소스 파일에 포함된 모든 리터럴의 목록이 있다. 해당 클래스 파일이 클래스 로더에 의해 메모리에 올라갈 때, 이 목록에 있는 리터럴들은 JVM의 Heap 영역인 Constant pool에 저장된다.

String을 초기화하는 방법은 이외에도 new String()을 쓰는 방법이 있다. 이 방법은 매번 새로운 객체를 생성하기 때문에 같은 문자열을 사용해도 다른 객체로 구분된다.

String a = "abc";
String b = "abc";

String c = new String("abc");
String d = new String("abc");

System.out.println(a == b); // true
System.out.println(c == d); // false

🔍 StringBuffer Vs StringBuilder

StringBuffer는 멀티쓰레드에 안전(thread safe)하도록 동기화 되어 있고, StringBuilder는 동기화를 지원하지 않는다. 따라서 StringBuilder는 멀티쓰레드 환경에서 사용하는 것은 부적합하지만 단일쓰레드에서는 성능이 더 뛰어나다. 이 두가지는 이름 빼고는 완전히 똑같은 기능으로 작성되어 있다.


Reference

Java의 정석 - 3rd Edition by. 남궁 성

profile
개발 공부 일지

0개의 댓글