Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

자바(Java) 문자열 인턴(String Interning)의 개념과 동작 원리

문자열 인턴십(String Interning)이란?

문자열 인턴십은 서로 구별되는 모든 문자열 값에 대해 단 하나의 복사본만 저장하는 기법입니다. 자바에서 String 객체는 한 번 생성되면 내용을 변경할 수 없는 불변(immutable) 객체이므로, 동일한 데이터를 가진 여러 문자열이 하나의 메모리 공간을 공유할 수 있습니다. 이러한 방식 덕분에 프로그램 전체의 메모리 사용량을 크게 줄일 수 있습니다.

intern() 메서드 호출 시의 동작

  • 먼저 두 문자열 간의 동등성을 검사합니다. 즉, 해당 문자열 객체가 이미 문자열 상수 풀(String Constant Pool, SCP)에 존재하는지 확인합니다.

  • 풀에 이미 존재한다면 해당 문자열을 풀에서 가져와 반환하고, 존재하지 않는다면 새로운 String 객체를 생성하여 풀에 추가한 뒤 그 객체의 참조값을 반환합니다.

  • 따라서 두 문자열 a, b에 대해 a.intern() == b.intern()이 참일 필요충분조건은 a.equals(b)가 참을 반환하는 경우입니다.

예제 코드

public class Demo {
    public static void main(String[] args) {
        String s1 = new String("Its");
        String s2 = s1.concat("sample");
        String s3 = s2.intern();
        System.out.println("객체 2와 객체 3의 동등성 확인 :");
        System.out.println(s2 == s3);
        String s4 = "Its a sample";
        System.out.println("객체 3과 객체 4의 동등성 확인 :");
        System.out.println(s3 == s4);
    }
}

실행 결과

객체 2와 객체 3의 동등성 확인 :
true
객체 3과 객체 4의 동등성 확인 :
false

코드 해설

Demo 클래스에는 main 메서드가 정의되어 있으며, 여기서 세 개의 String 객체 인스턴스가 선언됩니다. 첫 번째 문자열 s1은 new 키워드로 생성되어 힙 영역에 새로 할당되고, 두 번째 문자열 s2는 s1에 다른 값을 연결(concat)하여 만들어집니다. 세 번째 문자열 s3는 s2에 대해 intern()을 호출한 결과입니다.

s2와 s3의 경우, intern() 호출 당시 풀에 존재하지 않던 문자열이 상수 풀에 등록되면서 두 변수가 같은 객체를 가리키게 되므로 '==' 비교 결과 true가 출력됩니다. 반면 s4는 리터럴 "Its a sample"로 초기화된 문자열로, s2·s3의 내용("Itssample")과는 다른 별개의 문자열이므로 서로 다른 객체이며, 비교 결과 false가 됩니다.

추가로 알아두면 좋은 점

JDK 7 이전에는 문자열 상수 풀이 PermGen(영구 생성 영역)에 위치했지만, JDK 7부터는 힙 영역으로 이동했습니다. 또한 실무에서는 문자열 비교 시 '==' 연산자보다 equals() 메서드를 사용하는 것이 권장되며, intern()은 동일한 문자열이 대량으로 반복되는 특정 상황에서 메모리 최적화 목적으로 유용하게 활용할 수 있습니다.