J-S-11 String의 특징과 Wrapper Class

글 정보
카테고리
Programming/Java/Starter
태그
JavaLevel2

1. String과 상수 풀 (String Constant Pool)

String의 특징과 메모리 관리

자바의 문자열(String)은 불변(Immutable) 구조를 가집니다.

모든 문자열 리터럴은 상수 풀(String Constant Pool)에 저장됩니다.

동일한 문자열 리터럴("")을 생성하면, 풀 내의 같은 객체를 참조하게 만듭니다.

String.intern() 메서드

Native 메서드로 구현되어 있습니다.

리터럴("")로 상수를 선언하면 내부적으로 intern()이 호출됩니다.

[동작 원리]

  1. 상수 풀에서 해당 리터럴 문자열을 검색합니다.
  2. 있으면: 이미 생성된 인스턴스를 반환합니다.
  3. 없으면: 새로 생성하여 풀에 추가한 뒤 반환합니다.

메모리 위치의 변화 (Java 7 전후)

Java 7 이후, 문자열 상수 풀의 위치가 변경되었습니다.

이로 인해 상수 풀에 저장된 문자열도 GC(Garbage Collection)의 대상이 됩니다.

상수 풀(Constant Pool)의 흐름과 생명주기

"A String Literal is always of type String"

문자열 상수는 시점에 따라 다른 공간을 거쳐갑니다.

  1. 컴파일 타임 (Compile Time)
    • .class 파일 내의 Constant Pool에 저장됩니다.
  2. 로딩 타임 (Loading Time)
    • 클래스 로드시 Runtime Constant Pool (Method Area)로 이동합니다.
  3. 실행 타임 (Runtime)
    • 실제 코드 실행 시 String Constant Pool (Heap Area)로 이동합니다.
    • 이때 intern() 메서드를 통해 중복 제거 및 캐싱이 이루어집니다.


2. StringBuilder: 가변(Mutable) 문자열

개요

불변(Immutable)인 String의 단점을 해결하기 위해 등장했습니다.

핵심 특징

가변(Mutable) 객체입니다.

값 변경 시 임시 객체를 생성하지 않습니다.

[주요 메서드]

성능 및 사용 가이드

String과 비교했을 때 연산 속도 차이가 압도적입니다.

문자열 변경이 잦은 로직에서는 반드시 사용해야 합니다.

[참고] StringBuilder vs StringBuffer

- StringBuilder: 동기화(Synchronization) 미지원 → 싱글 스레드 환경에서 가장 빠름.
- StringBuffer: 동기화 지원 → 멀티 스레드 환경에서 안전(Thread-Safe)하지만 상대적으로 느림.

코드 예시

public class StringBuilderExample {
    public static void main(String[] args) {
        // 1. 객체 생성 (가변 공간 확보)
        StringBuilder sb = new StringBuilder("Java");

        // 2. append(): 뒤에 내용 추가 (메모리 주소는 그대로, 내용만 바뀝니다)
        sb.append(" Script"); 
        // 현재 상태: "Java Script"

        // 3. insert(): 특정 위치(4번 인덱스)에 내용 끼워 넣기
        sb.insert(4, "Object"); 
        // 현재 상태: "JavaObject Script"

        // 4. delete(): 범위 삭제 (4번부터 10번 앞까지)
        sb.delete(4, 10); 
        // 현재 상태: "Java Script"

        // 5. reverse(): 문자열 전체 뒤집기
        sb.reverse(); 
        // 현재 상태: "tpircS avaJ"

        // 6. toString(): 최종 결과를 불변인 String으로 변환
        String finalResult = sb.toString();
        
        System.out.println(finalResult);
    }
}

3. 래퍼 클래스 (Wrapper Class)

등장 배경

자바의 기본 데이터 형식(Primitive Type)은 클래스가 아닙니다.

이러한 한계를 해결하기 위해 기본 타입을 클래스로 감싼 것이 래퍼 클래스입니다.

종류

박싱과 언박싱 (Boxing & Unboxing)

박싱(Boxing)

언박싱(Unboxing)

[주의] 값 비교 시

- 래퍼 클래스는 객체이므로 == 연산자는 주소값을 비교합니다.
- 값 자체를 비교하려면 .equals()를 사용해야 합니다.
- (단, Integer의 경우 -128 ~ 127 범위는 캐싱되어 == 비교가 가능할 수 있으나, 안전하게 .equals() 사용을 권장합니다.)