원래 String만 불변객체인줄 알고 있었다.
- 내가 알고 있던 불변객체의 특징
1. 상속이 불가하도록 final 클래스
2. 모든 필드가 final
- 자바에 불변 객체가 있는 이유
: 완전히 생성된 이후에도 내부가 유지되는 객체
1. 메모리상 유리함 (객체생성횟수 감소)
2. 멀티쓰레드 환경에서 Thread-safe함.
3. 캐시에 용이

String 클래스 또한 불변객체이므로 내부에 hash code 를 캐싱한다.
-> 불변객체이기때문에 캐시에 유리하다.
(데이터의 수정/삭제/추가가 적을 수록 캐시에 유리하다.)
-> Integer 클래스에서 내부적으로 -128~127 을 캐시한다는 것도 최근에 알았지만 당시 불변객체와 연결 짓지는 못했다.
https://dont-be-evil.tistory.com/276
# String은 왜 불변객체인지 알아보자.
- String 은 자바에서 유일하게 리터럴로 초기화, new 키워드로 초기화가 가능한 타입이다.
자바는 왜 이렇게 만들어 두었을까?
1. 아시다시피 primitive type의 경우 Stack에 변수와 값이 모두 올라간다.
2. 하지만 레퍼런스타입인 String은 힙에 올라간다.
3. 이때 리터럴로 초기화 시 Heap의 String Pool에 할당된다.
4. 이후 같은 문자열을 초기화 시 같은 String Pool의 문자열을 가리키게 되어 메모리상 유리하다.
- 자바가 String을 불변객체로 만들어 둔 이유
1. String Pool에서 관리하기 위해. -> runtime에서 heap 영역의 많은 메모리를 절약할 수 있다.
-> String이 불변이 아니었다면 해당 메모리의 값이 언제 바뀔지 알 수 없기 때문에 String pool 형태로 관리 할 수 없다.
2. 보안상의 이유. DB의 userid, password, 소켓통신에서의 host와 port의 정보는 String으로 다뤄지기 떄문에 String이 불변객체임으로써 보안상 유리하게 된다.
3. String은 불변이기 때문에 멀티쓰레딩 환경에서 Thread-safe하다. -> 동기화 걱정 안해도된다.
4. 이건 이유는 아니지만 자바는 String의 생성단계부터 hashcode값을 캐시한다.
-> hashcode를 key로 사용하는 hashmap의 경우 매우 빠르다. -> String이 불변이기 때문에 캐싱을 할 수 있었다.
# Wrapper 클래스도 불변객체였다.
: 기본형 변수를 감싸는 래퍼클래스 -> 컬렉션에서 사용 시 객체로 취급하기 위함.

Integer에 두가지가 있다. 래퍼클래스는 원시타입보다 메모리 5배 -> 꼭 필요하지 않으면 parse하자.
Integer의 생성자는 현재 자바11기준 deprecated 되었다.
-> valueOf, parseInt 메서드를 사용하자.
-> 하지만 보통의 경우 오토박싱, 오토언박싱을 이용한다.
공식문서에도 Wrapper클래스는 생성자를 통한 생성보다 정적팩토리메서드를 사용하라고 되어있다.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Integer.html#%3Cinit%3E(int)
참고 : https://www.baeldung.com/java-string-immutable
꾸준히 다시보자.
1. 220925
2. 221003
3. 221029
'새롭게 쌓은 지식' 카테고리의 다른 글
Map 인터페이스의 merge() 메서드 (0) | 2022.09.26 |
---|---|
캐시에 대하여 (0) | 2022.09.26 |
Integer클래스는 캐시를 사용한다. (0) | 2022.09.17 |
Spring ArgumentResolver와 Interceptor (1) | 2022.09.14 |
여러 프로그래밍 팁 (0) | 2022.09.10 |