들어가며
JAVA를 처음 접할 때, String은 불변객체라고 배우고 지나갔습니다. 하지만 실제 String을 다루다보면 어째서 불변객체인지 의문이 들곤합니다.
String str = "apple";
str = "banana";
왜냐하면, 재할당에 대해서 문제가 없으니까요.
그런데 무슨 불변성이 있다는 것일까요? 이 글에서는 String 이 왜 불변성을 가지는지 알아보겠습니다.
1. String은 참조타입이다.
String의 불변성을 얘기하기 전에 알고 넘어가야할 부분이 몇가지 있습니다.JAVA에서 String 은 기본타입이 아닌 참조타입인 클래스라는 것입니다.
String str1 = "apple";
String str2 = "apple";
System.out.println(str1 == str2); // true
String str1 = new String("apple");
String str2 = new String("apple");
System.out.println(str1 == str2); // false
"" (큰따옴표)로 생성한 객체는 내용이 같으면 같음 메모리 주소를 가집니다.
new 연산자로 생성한 객체는 내용이 같더라도 다른 메모리 주소를 가집니다.
2. String Constant Pool
String은 Heap 영역에서 String Constant Pool 에서 관리되고있습니다.
""(큰따옴표)로 생성된 객체는 String Constant Pool 에서 관리되어 다음 동일한 값이 할당된다면 이전에 있던 참조값을 반환해줍니다. ( == true)
new 연산자를 사용한다면 String Constant Pool에 같은 값이 존재하더라도 별도의 주소를 가리키게됩니다. ( == false)
만약 위 그림에서 str2 = "apple" 이었다가 "banana"로 값이 변경된다면 어떻게 될까요?
변수 str2의 값이 "banana"로 변경된다면 String Constant Pool에서 값이 "banana"인 주소를 찾고 없다면 새로 생성하여 그 주소를 반환해줍니다. 이 과정에서 이전의 "apple" 데이터는 변경되지 않습니다.
불변인 이유
- String Constant Pool에서 String 을 관리한다는것은 동일한 데이터에 대해 메모리주소를 공유함으로써 Heap 영역의 메모리가 절약한다는 뜻이됩니다. 이 과정에서 String 이 불변성을 유지해야지 메모리 주소를 공유하는 것이 가능합니다.
만약 String이 불변객체가 아니라면 변수 str1과 str2가 "apple" 의 메모리주소를 공유하고있다고했을때 str2에서 값이 변경되는 순간 str1도 값이 변경되기 때문에 불변성을 가져야합니다. - String 객체에 대해 hashCode를 미리 계산하지 않아 메모리를 절약하고, 필요할 때만 계산하고, 계산된 후에는 재사용하여 성능을 향상 시킵니다. hashCode를 재사용한다는 것은 String의 불변성이 보장되어야 가능합니다. hashCode의 캐싱은 HashMap, HashSet과 같은 hash를 사용하는 연산에서 효과적입니다. 일반 객체는 사용할때마다 hashCode를 계산하지만 String은 캐싱된 hashCode를 사용하기 때문에 더욱 빠르게 연산하는 것이 가능합니다.
- Sring은 불변이기 때문에 Thread-Safe합니다. 값이 변경되지않는 것이 보장된다면 동기화 문제가 발생할 수가 없습니다.
- String이 불변이 아니라면 보안에 문제가 생길 수 있습니다. 데이터베이스의 username, password이나 host, port가 String값으로 전달된다고 했을때, 이 값이 불변이 아니라면 공격으로부터 값이 변경될 수 있기 때문입니다.
이상 String의 불변성에 대해서 알아보았습니다. 문자열의 기본타입이 존재하지않는 이유가 String의 불변성과 관련이 있다는 것을 알아가는 시간이었습니다.
'Language > JAVA' 카테고리의 다른 글
[JAVA] If-else 와 switch 중에 어느게 더 빠를까? (0) | 2024.09.24 |
---|---|
[JAVA] StringBuilder, StringBuffer 의 차이점과 주의사항 (0) | 2024.09.23 |
[JAVA] 함수형 인터페이스에 대해서 알아보자 (0) | 2024.09.15 |
[JAVA] Collection List를 최적화해보자 (0) | 2024.03.18 |
[JAVA] 직렬화(Serialization)와 역직렬화(Deserialization) (0) | 2024.02.14 |