콘텐츠로 건너뛰기

String 객체의 불변성

# 불변성 (Immutability) : 해당 객체의 정보가 변하지 않는 것

불변(immutable) 클래스란 인스턴스가 변경되지 않는 클래스를 가리킨다.

자바 플랫폼에서 String, 박싱(boxing)된 원시 클래스, BigInteger, BigDecimal이

이러한 불변 클래스에 해당한다.

불변 클래스의 장점은 변하는(mutable) 클래스보다 설계, 구현 및 사용이 쉽다는 점이다.

String s = “0”;
f
or (int x = 1; x < 10; x++) {
    s = s + x;
}

>> s = “0123456789”

하지만 String 객체는 불변성을 가지기때문에 String 상수 10개 생성된다.

(0 01 012 0123 01234 … 01234567890)

새로운 String을 만들 때 JVM에서는 그 상수를 “String 풀” 이라는 메모리 공간에 할당한다.

새로 생성된 String의 값은 변경할 수 없고,

대신 이후에 동일한 String 값이 들어오게 되는 경우에는

새로 생성하지 않고 기존에 있던 값에 참조를 걸게 된다.

그런데 가비지 컬렉터는 String 풀 영역에서는 동작하지 않는다.

즉, String을 생성하면 그 상수객체는 계속해서 메모리 영역을 차지하게 된다.

이러한 String 상수객체의 불변성 때문에 문자열 결합에서 성능이 저하될 수 있다.

// AS-IS :
public String statement() {
    String result = “”;
    for (int i = 0; i < numItems(); i++) {
        result += lineForItem(i);
    }
    return result;
}

// TO-BE :
public String statement() {
    StringBuilder sb = new StringBuilder(numItems() * LINE_WIDTH);
    for (int i = 0; i < numItems(); i++) {
         sb.apped(lineForItem(i));
    }
    return b.toString();
}

StringBuilder 의 크기를 정해주면 + 연산에 비해 85배 가량 빠르고,

default 크기로 사용해도 50 배 가량 빠르다. (머신에 따른 차이는 있음)

long startTime, endTime;

String s = new String();
startTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
    s += ‘a’;
}
endTime = System.currentTimeMillis();
System.out.println(“String : ” + (end-start));

StringBuffer sb = new StringBuffer();
start = System.currenTimeMillis();
for (int i = 0; i < 100000; i ++) {
    sb.append(‘a’);
}
end = System.currentTimeMillis();
System.out.println(“SB : ” + (end-start));

>> String : 19297
>> SB : 0

출처 : Head First Java, Effective Java, 인터넷

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다