불변 == 읽기 전용 클래스
사이드 이펙트와 참조자
- 특정 인스턴스에 대한 참조는 여러 개가 될 수 있으며 이를 막을 수도 없음
- 매개변수, 멀티스레딩 환경
- 모든 참조는 대상 인스턴스에 대한 읽기, 쓰기, 접근(Mutable)이 모두 허용
- 참조자 및 메서드 통한 필드 값 변경을 제어할 수 있는 문법 없음
- 인스턴스에대한 무결성을 보장해야하는 구조에서 (논리적) 문제가 발생할 수 있음
불변 객체의 정의
- 모든 필드를 final 선언함으로써 상수화한 클래스 (무결성)
- 필드 초깃값을 기술할 수 있는 부분 제외(생성자 또는 초깃값 정의)
- 필드 값을 변경해야 한다면 새로운 사본 인스턴스를 생성하면서 원하는 수정된 초기값을 기술해 반환하는 구조로 개발(원자성 보장)
- 비효율적일 수 있으나 멀티스레딩 환경에서 장점 존재
- 대표적 불변 객체
- String, Wrapper class
문자열 상수와 String
- 문자열의 본질은 문자 배열이며 문자열은 인코딩 규칙에 영향을 받음
- char[], String
- 문자 배열은 겹따온표를 이용한 리터럴 표기 가능
- Java 9 이후 char[]에서 byte[] 로 변경
- String 클래스는 불변 클래스이며 논리적 의미로 기본 형식에 속하는 특성을 보임
- 덧셈 연산의 결과로 임시 객체가 생기는 문제가 있음
- 큰 문자열을 다룰 경우 효율이 더 떨어짐
문자열은 가변일 수 있는데 배열로 표현한다?
이번 섹션 3강 매우 내용이 좋다. 문자열끼리 연산의 오버헤드를 잘 설명해줌!
문자열 비교
- 상등 연산으로 두 String 클래스 인스턴스를 비교할 경우 심각한 논리적 문제가 있을 수 있다
- 문자열 상수 풀
- JVM이 클래스 로딩 시 미리 인스턴스 생성
- equals() 를 쓰거나 compareTo() 로 문자열 비교하는 것이 적절
Java(JVM)가 문자열을 관리하는 구조
모든 문자열은 상수 풀로 관리
- C/C++ 로 개발된 PE 파일과 유사한 구조
- .exe 파일의 내부에 문자열이 포함
- 실행 코드가 저장되는 정적 메모리 영역에 문자열 상수 저장
- 같은 문자열 상수에 대한 포인터의 주소는 모두 동일
- 코드상 존재하는 모든 문자열 상수(리터럴)은 Class가 로딩될 때 Runtime constant pool 에 등록된 후 힙 영역에 존재하는 String constant pool 에도 추가(String객체)
String.intern()
public native String intern();
- native 는 C/C++로 구현된 메소드에 붙이는 예약어
- 문자열 상수 선언 시 내부적으로 intern() 함수 호출
- String s1 = “Hello”;
- 문자열 상수 풀에서 문자열을 조회하고 ‘무조건’ 반환
- 문자열 상수와 일치하는 문자열을 상수 풀에서 검색
- 찾으면 이미 생성되어 있는 String 인스턴스 반환
- 없으면 새로 String 객체 생성 후 풀에 추가하고 반환
- 문자열 상수 풀은 힙 영역(Java 7 이후)에 속하며 GC 대상
두 개의 상수 풀
A string literal is always of type String
- .class 파일 Constant pool 에 저장(컴파일)
- Runtime constant pool로 이동(로딩)
- String costant pool로 이동(실행)

내용을 변경하는 StringBuilder
- 불변 객체인 String 의 단점을 해결하기 위해 만들어진 가변 String
- 문자열 값 변경시 임시 객체 만들지 않고 인스턴스 데이터 직접 수정
- append()
- insert()
- delete()
- reverse()
- toString()
래퍼 클래스
- 기본 데이터 형식은 클래스가 아니므로 메소드를 가지지 못함
- 이 문제 해결하기 위해 기본 데이터 형식으로 클래스로 만든 것이 Wrapper class
- Byte, Character, Short, Integer, Long, Float, Double, Boolean
박싱과 언박싱
- 기본 형식을 래퍼 클래스로 만드는 경우가 박싱
- Character obj = new Character(‘A’);
- Integer obj = new Integer(123);
- Integer obj = new Integer(“123”);
- Integer obj = Integer.valueOf(“123”);
- Integer obj = 123;
- 래퍼 클래스에서 기본 데이터 값을 얻는 것이 언박싱