자바에서는 문자열이 불변 객체로 처리되며, 메모리 내부에 저장되는 방식에 대해 많은 개발자가 관심을 갖습니다. 실제로 자바는 객체의 직접적인 메모리 주소를 제공하지 않지만, 간접적인 방법을 통해 문자열 객체의 고유 식별 정보를 확인할 수 있습니다.
identityHashCode를 통한 객체 식별
System.identityHashCode() 메서드는 객체의 해시 코드를 반환하며, 이 값은 객체가 메모리 상에서 어떻게 배치되었는지를 암시적으로 나타낼 수 있습니다. 이 값은 실제 주소가 아니지만, 동일한 객체에 대해 일관된 결과를 보장합니다.
public class StringIdentityExample {
public static void main(String[] args) {
String text = "안녕하세요, 자바!";
int hash = System.identityHashCode(text);
System.out.println("문자열 \"" + text + "\"의 해시값: " + hash);
}
}
toString() 메서드를 활용한 객체 식별
모든 객체는 Object 클래스를 상속하므로 기본적으로 toString() 메서드를 사용할 수 있습니다. 문자열 객체는 해당 메서드를 오버라이드하지 않았기 때문에, 클래스 이름과 16진수 해시코드를 포함한 형태로 출력됩니다.
public class StringDisplayExample {
public static void main(String[] args) {
String sample = "자바 문자열 예제";
System.out.println("객체 식별 정보: " + sample.toString());
}
}
출력 예시:
객체 식별 정보: 자바 문자열 예제@12345678
문자열 상수 풀의 작동 원리
자바는 문자열 리터럴을 효율적으로 관리하기 위해 상수 풀(String Pool)을 사용합니다. 동일한 문자열 리터럴이 여러 번 생성될 경우, 기존에 존재하는 객체를 재사용하여 메모리 절약을 도모합니다.
public class StringPoolDemo {
public static void main(String[] args) {
String a = "Hello";
String b = "Hello";
System.out.println("a와 b가 같은 객체인가? " + (a == b));
}
}
출력 결과:
a와 b가 같은 객체인가? true
이처럼 동일한 리터럴은 같은 참조를 공유하므로, 메모리 사용량을 최적화할 수 있습니다.
정리
자바에서는 문자열의 실제 메모리 주소를 직접 조회할 수 없지만, System.identityHashCode()와 toString()을 통해 객체의 고유 식별 정보를 얻을 수 있습니다. 또한 문자열 상수 풀의 개념을 이해하면 메모리 효율성과 객체 비교 로직에 대한 깊은 이해가 가능합니다.