자바에서 Sring은 불변(Immutable) 객체이다.
불변 객체란?
불변 객체란, 객체가 생성된 후 내부의 상태가 변하지 않고 계속 유지되는 객체를 말한다.
즉, 변수에 객체가 한 번 할당되면 해당 객체의 참조를 변경할 수도, 내부의 상태를 수정할 수도 없는 것이다.
1. String Pool
String이 불변이기 때문에 String Pool도 존재할 수 있다.
자바에서는 String Pool이라는 공간에 String을 포함시켜서 매번 String 객체를 새로 생성하기 보다는 값이 같은 String이라면 String Pool에 있는 객체를 재사용할 수 있도록 구현했다.
위 예시에서 s1의 값을 "Hi World"로 바꾼다면 s1은 String Pool 내부의 다른 String 객체를 바라보게 된다.
하지만 만약 String이 mutable하다면?
s1의 값만 "Hi World"로 바뀌고 s2는 그대로 "Hello World"인 셈인데, 값이 다른데 같은 참조를 가진다는 것은 말이 안된다.
즉 String 타입이 mutable하다면, String 객체끼리의 공유가 불가능하게 된다.
2. 보안
자바에서 메소드의 매개변수로 String을 받는 경우는 매우 흔하다.
만약 String이 mutable하다면, 메소드의 인자로 받은 값은 메소드의 caller(호출자)에 의해 언제든지 바뀔 수 있게 된다.
이는 보안상의 엄청난 취약점을 발생시킨다.
3. 동기화(Synchronization)
객체가 불변이면 멀티쓰레드 환경에서도 값이 바뀔 위험이 없기 때문에, 자연스럽게 Thread-Safe한 특성을 갖게 되고, 동기화와 관련된 위험 요소에서 벗어날 수 있다.
여러 쓰레드에서 동시에 접근해도 별다른 문제가 없다.
또한 String의 경우 한 쓰레드에서 값을 변경하면, 해당 객체의 값을 수정하는 것이 아니라 새로운 객체를 String Pool에 생성하므로 Thread-Safe하다고 볼 수 있다.
4. HashCode Caching
String의 hashCode() 메소드 구현을 보면, 아직 hash 값을 계산한 적이 없을 때 최초 한 번만 계산 로직을 수행한다.
이후부터는 이전에 계산했던 값을 그냥 리턴하도록 되어있다.
즉, hashCode 값을 캐싱하고 있다.
이렇게 캐싱이 가능한 것도 결국 String이 불변이기 때문에 얻을 수 있는 이점이다.
hashCode() 메소드는 Hash 자료구조의 구현체, 예를 들면 HashMap, HashTable, HashSet과 같은 클래스에서 자주 호출된다.
String 객체와 함께 Hash 구현체를 사용하는 경우라면 이러한 캐싱 덕분에 성능상 큰 이점을 볼 수 있을 것이다.
5. 성능
위에서 나온 내용들을 종합해보면, String이 불변 객체임으로써 성능면에서 유리하다는 것을 알 수 있다.
String은 상대적으로 자주 쓰이는 타입이기 때문에, String의 성능을 개선하는 것은 전체 프로그램의 성능에도 긍정적이 영향을 주게 된다.
'2022 하계방학 SW 집중교육' 카테고리의 다른 글
[Github] .gitignore (0) | 2022.08.15 |
---|---|
[Java] Exception (0) | 2022.08.15 |
[Java] toString() (0) | 2022.08.15 |
[Java] Package (0) | 2022.08.15 |
[Java] Thread (0) | 2022.08.15 |