Java에서 문자열을 표현할 때 가장 많이 사용하는 class는 무엇일까?

단연 String, StringBuilder, StringBuffer 이 세 개를 꼽을 수 있다.

그럼 이 비슷해보이는 세 개의 class의 차이점은 무엇일까?

먼저 Stringimmutable 즉, 불변한 클래스다.

상태값이 변경하지 않는 것을 의미한다.

다음은 Java 8String이다.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];

    private int hash; // Default to 0

바로 알겠지만 String에 value는 final이다.

char형태의 array이고 private이다.

String에 존재하는 값인 value는 final로

더 이상 변경할 수 없게 했고 class에도 final을 넣어 상속불가능하게 하였다.

즉, 위 Stringcode를 보면 알겠지만 Stringimmutable하다.

immutablethread에 safe하다.

불변이기 때문에 어떤 thread가 접근을 해도 상태를 변경할 수 없기 때문이다.
Effective Java p.103 에서도 찾아볼 수 있다

그럼 StringBuilder는 어떨까?

StringBuilder 또한 직접 소스를 보자.

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    public StringBuilder() {
        super(16);
    }

    public StringBuilder(int capacity) {
        super(capacity);
    }

    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }

    public StringBuilder(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }

위 소스는 Java 8StringBuilder 이다.

자세히 보면 StringBuilderconstructor를 보면 append()를 통해 append를 실행한다.

append()는 여러가지 argument type을 지원하므로 overloading이 되어 있다.

그 중 우리가 자주 쓸만한 것을 가져왔다.

@Override
public StringBuilder append(Object obj) {
    return append(String.valueOf(obj));
}

@Override
public StringBuilder append(String str) {
    super.append(str);
    return this;
}

자 보면 appendthis를 반환한다. 거진 대부분의 append가 두 번째 append()append(String str)

유사한 형태이다.

return this;이다.

자기 자신 즉, StringBuilder를 반환한다.

그리고 StringBuilder를 보면 super.append();가 있다.

이 녀석을 추적해보면 구현한 interfaceAbstractStringBuilder를 보면

String.getChars를 사용하고 있고 이것을 찾아보면 System.arrayCopy를 통해서

String을 카피해서 해서 주는 걸로 보인다.

또한, StringStringBuilder가 계속 가지고 있으면서 복사본을 주는 것으로 보여진다.

StringBufferStringBuilder와 똑같이 동작하며,

class의 차이점은 각 메서드에 synchronized의 유/무다.

즉, thread safeStringBuffer이고, thread unsafeStringBuilder이다.

StringBuilderStringBuffer의 차이점은 동기화 지원 여부를 제외하고는 없는 것으로 보여진다.

정리하면 다음 표와 같다.

class mutable thread safe
String immutable thread safe
StringBuilder mutable thread unsafe
StringBuffer mutable thread safe