
불변이라면, 한번 생성하고나면 변하지 않는다는 말일 것이다.
예를 들어서
s = "hello"
s = s + "world"
이렇게 적혀있다면, hello world 라는 새로운 문자열 객체가 만들어진 것일 뿐 기존 hello는 변하지 않는다고 한다.
이 말은, hello라는 문자열이 저장된 메모리 주소가 있을 것이고 s는 해당 위치를 지칭할 것이다. 이때 hello + world가 되게 되면, hello라고 저장된 메모리 위치에서 수정이나 hello world라는 문자열로 덮어쓰기가 일어나는 것이 아닌 해당 객체가 새로운 메모리 주소로 할당되며 생성되고 s는 새롭게 해당 주소를 지칭하게 된다. 여기까지는 이해가 되는데 그렇다면 왜 이렇게 만들었을까.
이점 :
String first = "hello"; // 리터럴로 생성
String second = new String("hello"); // 생성자로 생성
String third = "hello";
System.out.println(System.identityHashCode(first)); // 498931366
System.out.println(System.identityHashCode(second)); // 2060468723
System.out.println(System.identityHashCode(third)); // 498931366
해당 두 객체는 다른 객체임. 리터럴로 생성한 String 객체는 Heap영역의 String Constant Pool에 저장되어 동일한 문자열을 재사용 가능함.
반면, 생성자로 생성한 String 객체는 Heap영역에 저장되어 동일한 문자열이더라도 항상 새로운 객체 생성함.
String third = second.intern(); // intern() 메서드 사용
System.out.println(System.identityHashCode(third)); // 498931366
intern() 메서드를 사용하면 Heap 영역에 저장된 String객체를 String Constant Pool에 저장 할 수 없음.
intern() 메서드는 해당 문자열이 String Constant Pool에 존재할 경우 그 주솟값을 반환하고, 없을 경우 String constant Pool에 추가하고 새로운 주솟값을 반환
그렇다면 파이썬도 비슷한 게 있나?
챗지피티로 물어본 결과

생성자로 만든 문자열은?
자바처럼 무조건 새 객체는 아님. 이미 문자열이 있다면, 그냥 그 객체를 반환해줌
-> intern()을 sys라이브러리의 내부 함수로 사용 가능함. 하지만 항상 intern되는 것은 아님.
짧은 리터럴, 영문자/숫자/언더 스코어로만 된 문자열 등 일부만 자동 intern
복잡하거나 동적으로 만들어진 긴 문자열은 필요에 따라 intern 해야 공유 가능
하지만, 결론적으로 파이썬도 자바처럼 문자열 불변성, 상수 객체 공유 구조는 존재함.
| [매일메일] Infrastructure as Code (Iac)에 대해 설명해주세요 (0) | 2025.07.10 |
|---|---|
| [매일메일] @OneToOne 연관관계에서 Lazy Loading을 설정할 때 주의할 점은? (3) | 2025.07.10 |
| [매일메일] 네트워크에서 회선 교환 방식과 패킷 교환 방식은 어떤 차이점이 있나요? (0) | 2025.07.07 |
| [매일메일] try-with-resources에 대해 설명해 주세요 (0) | 2025.07.04 |
| [매일메일] Micrometer가 무엇인지 설명해주세요 (0) | 2025.07.03 |