8월 8일 - Interned String in Java

Yullgiii·2024년 8월 8일
0

Interned String in Java

자바(Java)에서는 문자열(String)은 불변(immutable)한 객체이다. 문자열에 대한 연산을 수행하면, 기존 객체를 수정하지 않고 새로운 객체를 반환한다. 그러나 항상 새로운 객체가 생성되는 것은 아니다. 이를 이해하기 위해 몇 가지 예제를 살펴보자.

문자열 불변성과 같은 객체 반환

다음 예제는 toUpperCase() 메서드의 동작을 설명한다.

public void example1() {
    String fruit1 = new String("BANANA");
    String upperFruit1 = fruit1.toUpperCase();
    System.out.println(fruit1 == upperFruit1); // true
}

"BANANA" 문자열에 대해 toUpperCase()를 호출하면, 결과는 기존 객체와 같은 객체가 된다. 이는 toUpperCase() 메서드가 문자열 내에 소문자 문자를 발견하지 못할 경우 기존 객체를 반환하기 때문이다.

생성자와 리터럴 비교

new 키워드를 사용하여 문자열을 생성하면, 힙(heap)에 새로운 객체를 생성한다. 이를 확인하는 예제는 다음과 같다.

public void example2() {
    String fruit2 = new String("APPLE");
    String fruit3 = "APPLE";
    System.out.println(fruit2 == fruit3);        // false
    System.out.println(fruit2.equals(fruit3));   // true
}

fruit2와 fruit3는 같은 값을 가지지만 서로 다른 객체이다. 따라서 == 비교는 false를 반환하고, equals() 메서드는 true를 반환한다.

리터럴과 String.valueOf() 비교

리터럴로 선언한 문자열과 String.valueOf()로 가져온 문자열은 동일한 객체로 처리된다. 다음 예제는 이를 설명한다.

public void example3() {
    String fruit4 = "ORANGE";
    String fruit5 = String.valueOf("ORANGE");
        
    System.out.println(fruit4 == fruit5);        // true
    System.out.println(fruit4.equals(fruit5));   // true
}

위의 예제에서 두 문자열은 동일한 객체이다. 이는 String.valueOf() 메서드가 내부적으로 객체의 toString()을 호출하고, toString() 메서드가 this를 반환하기 때문이다. 결국, 리터럴 "ORANGE"와 String.valueOf("ORANGE")는 동일한 객체를 가리킨다.

상수 풀(Constant Pool)과 intern() 메서드

자바는 JVM 내에서 상수 풀(Constant Pool)을 사용하여 문자열을 관리한다. 리터럴로 선언된 문자열은 상수 풀에 저장되며, 이미 존재하는 문자열이 있으면 해당 객체를 반환한다. 만약 없으면 새로운 객체를 생성하고 상수 풀에 등록한다.

String.intern() 메서드는 문자열을 상수 풀에 등록하거나, 이미 등록된 객체를 반환하는 데 사용된다. 이를 통해 동일한 리터럴 문자열은 항상 같은 객체로 처리된다.

public void example4() {
    String fruit6 = new String("GRAPE").intern();
    String fruit7 = "GRAPE";

    System.out.println(fruit6 == fruit7);        // true
}

위 코드에서 fruit6은 intern() 메서드를 통해 상수 풀에 등록되고, fruit7과 동일한 객체가 된다.

So...

자바에서 문자열은 불변 객체이며, 리터럴 문자열은 상수 풀에 의해 관리된다. 이는 메모리 효율성을 높이고, 동일한 리터럴 문자열을 공유하여 성능을 최적화하는 데 기여한다. new 키워드를 통해 생성한 문자열은 항상 새로운 객체를 생성하므로, 이러한 차이를 이해하고 적절히 사용하는 것이 중요하다. intern() 메서드를 활용하여 문자열을 상수 풀에 추가하면, 동일한 문자열에 대해 항상 같은 객체를 참조할 수 있다.

profile
개발이란 무엇인가..를 공부하는 거북이의 성장일기 🐢

0개의 댓글