자바에서 String은 왜 Immutable일까?
결론
결론부터 말하자면 그냥 자바에서 String을 Immutable로 만드는 것이 더 좋다고 판단하였기 때문에 Immutable인 것이다.
그래서 질문을 바꿔 다시 물어봐야 한다.
왜 자바의 디자이너는 String을 Immutable로 설계하였을까?
디자인적인 측면
자바에서는 특별한 존재인 String을 String Constant Pool이라고 불리는 리터럴 String을 보관하는 영역이 heap에 따로 존재한다.
String이 기본 객체 중 가장 많이, 자주 사용되기 때문에 객체를 생성하고 제거하는데 드는 오버헤드를 최소화하기 위해 String만을 위한 특별한 메모리 구역을 heap 영역에 만들어두고 이를 HashMap 형태로 관리한다.
(String Constant Pool은 HashMap으로 구현되어있다.)
자바에서 Immutable하다는 것은 해당 메모리 주소에는 내가 정확하게 알고 있는 그 값이 있어야 한다는 의미이다.
이렇게 String을 관리하는 상수풀이 존재하려면 해당 메모리 주소가 가르키는 값은 항상 일정해야한다.
String이 Immutable이어서 String Constant Pool이 존재하는건지, String Constant Pool이 존재해서 String이 Immutable인지에 대해서는 정보가 잘 나오지 않아 확인하기 힘들었으나
String Constant Pool과 Immutable한 String은 항상 같은 맥락으로 이해해야 한다는 점은 변함없다.
Thread Safety
상술하였듯이 자바에서 Immutable하다는 것은 해당 메모리 주소에는 내가 정확하게 알고 있는 그 값이 있어야 한다는 의미이므로 어떤 스레드에서 어떤 시간에 어떻게 접근하든 해당 메모리는 내가 알고 있는 그 값을 정확하게 제공하므로 멀티스레딩 환경에서도 스레드 세이프한 접근이 가능해진다.
Caching
어떤 객체가 Immutable하다는 것은 해당 객체의 hashCode값 또한 언제나 일정한 값을 반환한다는 의미이기도 하다.
그 말은 즉 String의 메모리 주소를 한 번 알아두면 GC에 의해 제거될 때까지는 항상 같은 hashCode를 반환한다는 의미이다.
Immutable한 객체의 hashCode를 한번 캐싱해두면 Immutable한 특성 덕분에 어떠한 계산, 유효성 검사 등이 필요없이 매우 빠르게 동작할 수 있게 되는 것이다.
Class Loading & Security
만약 String이 mutable하다면 "java.io.Writer"이라는 클래스 로딩 요청이 "mil.vogoon.DiskErasingWriter"과 같이 변경될 수 있다.
(개인적으로 해당 설명이 String Immutable해야 하는 가장 적합한 설명이라 생각한다. 단 한 줄로 너무 명쾌하게 설명되었다.)
이외에도 String으로 처리되는 네트워크에서의 통신 처리나 파라미터 처리 등에서 mutable로 인해 생길 수 있는 수많은 보안적 이슈가 존재한다.
레퍼런스