가장 기본인 참조형 객체 String에 대해 알아보려고 합니다.
String 객체를 생성하는 데 방법은 두 가지가 있습니다.
첫 번째로 리터럴 방식("")으로 생성하는 것과 두 번째로 new 키워드로 생성하는 방법이 있습니다.
우선, 간단하게 String 객체를 저장하는 메모리 영역을 그림으로 보여드리겠습니다.
위 그림은 Java의 힙 메모리 영역입니다.
여기서 new 키워드로 String 객체를 생성하게 되면 Heap 영역에 메모리가 생성되고, 리터럴 방식으로 사용하게 된다면 Heap 영역의 내부에 있는 String constant pool 영역에 생성됩니다.
String은 불변성을 지니고 있어 한번 저장된 값은 변하지 않습니다. 그러면 자바는 내부적으로 String 객체를 업데이트할 때 기존에 있는 String 객체는 건드리지 않고 새로운 메모리를 할당해 String 객체를 생성합니다. 그래서 메모리 효율성면에서 비효율적일 수 있습니다. 그래서 String constant pool이라는 영역이 생겼습니다. 이 영역에 생성된 값이 같은 String은 같은 주소를 할당하기 때문입니다.
리터럴로 생성한 String은 내부적으로 intern() 메서드를 호출합니다. intern() 메서드는 주어진 문자열이 String constant pool 영역에 있는지 검색하여 존재하면 해당 주소를 반환하고, 없으면 새로 String constant pool 영역에 저장해 새로운 주소값을 반환합니다. 이 매커니즘으로 중복된 String 객체의 생성을 최소화해 메모리 효율성을 높입니다. 즉, intern() 메서드는 Heap 메모리에 있는 String 객체를 String constant pool 영역으로 옮겨주는 역할을 합니다.
여기서 intern() 메서드가 동등성을 확인할 땐 equals 메서드를 통해 확인합니다.
equals 메서드는 서로 다른 객체여도 String 객체의 문자열이 같은지를 확인합니다.
그리고 == 연산자는 같은 객체를 참조하고 있는지를 확인해줍니다.
그래서 일반적으로 리터럴 방식으로 문자열을 생성하는 방법이 메모리 효율성을 향상 시키기 때문에 권장되지만, 중요한 정보를 다루거나, 자주 변경되는 문자열, 동적으로 생성되는 문자열은 new 키워드를 통해 새로운 String 객체를 생성합니다.
'🖥 백엔드 개발 > 백엔드' 카테고리의 다른 글
[Java] 클라이언트 실제 접근 IP 주소 가져오기 (0) | 2024.08.06 |
---|---|
[Java] 함수(Function)와 메서드(Method)의 차이점 (1) | 2024.03.05 |