cs(with 매일메일)

[260121수] String객체는 가변일까요, 불변일까요? 그렇게 생각하신 이유도 함께 설명해주세요.

tea-spoon 2026. 1. 26. 09:48

String 객체는 불변이다. 

String 클래스는 내부적으로 final 키워드가 선언된 byte[] 필드를 사용해서 문자열을 저장하기 때문이다. 

또한, String은 참조 타입(Reference Type)이기 때문에 concat(), replace(), toUpperCase()와 같은 String메서드를 호출하면 새로운 String객체를 참조하고 기존 객체를 수정하지 않는다. 따라서 String 객체를 불변하게 유지할 수 있다. 

 

왜 불변으로 설계했을까?

- String Constant Pool을 사용할 수 있다. 

- 동일한 문자열의 String변수들은 같은 객체를 공유하기 때문에 메모리를 효율적으로 사용할 수 있다.

- 불변 객체는 멀티 스레드 환경에서 thread-safe하다. 문자열을 변경하면 String Constant Pool에 새로운 객체를 생성하기 때문에 동기화를 신경쓸 필요가 없다. 

- 해시코드를 한 번만 계산하고 이를 캐싱해서 재사용할 수 있다. 

- 비밀번호, 토큰, URL 등의 민감 정보를 안전하게 다룰 수 있다. 불변한 객체는 변경할 수 없기 때문에 민감한 정보가 예기치 않게 수정되는 것을 방지할 수 있다. 

 

리터럴로 생성한 String, 객체와 생성자로 생성한 String객체를 비교하면 어떤 차이가 있나?

두 방식으로 생성한 객체는 같은 문자열을 갖더라도 메모리 상에서 다르게 처리된다. 

String first = "hello"; // 리터럴로 생성
String second = new String("hello"); // 생성자로 생성
String third = "hello"; 

System.out.println(System.identityHashCode(first);  // 123
System.out.println(System.identityHashCode(second); // 456
System.out.println(System.identityHashCode(third);  // 123

 

리터럴 생성 - Heap영역 String Constant Pool에 저장 -> 이후 계속 같은 주소 참조

생성자 생성 - Heap영열에 저장되어 동일한 문자열이더라도 항상 새로운 객체를 생성

 

✨ 타입

기본 vs 참조

불변 vs 가변