Java

StringBuffer

1space 2025. 6. 22. 19:48

자바의 정석[기초편]으로 공부한 내용을 정리한 글입니다.

 

StringBuffer 클래스

StringBuffer 클래스는 문자열을 다룰 때 내용을 자유롭게 변경할 수 있도록 설계된 클래스입니다.

기존의 String 클래스는 한번 생성되면 그 내용을 바꿀 수 없는(immutable) 클래스였습니다. 즉, 문자열을 연결하거나 일부만 바꾸고 싶어도 새로운 문자열 객체를 다시 생성해야 했습니다.

→ StringBuffer는 이러한 단점을 보완하여 내용을 바꾸더라도 새로운 객체를 만들지 않고 기존의 객체에서 직접 변경이 가능합니다.

내부 구조

public final class StringBuffer implements java.io.Serializable {
    private char[] value;
    ...
}
  • 내부적으로 문자열을 char[] value 배열로 저장합니다.
  • 이 배열을 통해 문자열을 직접 변경할 수 있습니다.
  • 따라서 효율적으로 문자열을 조작할 수 있습니다.

 

StringBuffer 생성자

StringBuffer 클래스는 여러 생성자를 제공하여 다양한 방식으로 초기화할 수 있습니다.

생성자 종류

  1. StringBuffer(int length)
 
public StringBuffer(int length) {
    value = new char[length];
    shared = false;
}
  • length 크기의 문자 배열을 생성합니다.
  • 내부에서 문자열을 저장할 공간을 미리 확보합니다.
  1. StringBuffer()
 
public StringBuffer() {
    this(16);
}
  • 기본 생성자입니다.
  • 버퍼의 초기 크기를 16으로 설정합니다.
  • 즉, 내부 배열은 new char[16]으로 생성됩니다.
  1. StringBuffer(String str)
 
public StringBuffer(String str) {
    this(str.length() + 16);
    append(str);
}
  • 문자열 str의 길이보다 16만큼 더 큰 크기의 버퍼를 생성하고,
  • str의 내용을 내부 버퍼에 복사합니다.
  • 문자열 내용을 가진 StringBuffer 객체를 만들고자 할 때 자주 사용됩니다.

 

버퍼 크기 확장 방식

문자열이 계속 추가되다 보면 처음에 만든 char[]의 길이를 초과할 수 있습니다.
이 경우 Java는 다음과 같은 방식으로 버퍼를 자동으로 확장합니다.

char[] newValue = new char[newCapacity];
System.arraycopy(value, 0, newValue, 0, count);
value = newValue;
  • 새로운 배열(newCapacity)을 만들고,
  • 기존의 내용을 복사해서 저장한 후,
  • 내부 배열 value를 이 새 배열로 바꿉니다.

이 과정을 통해 기존의 StringBuffer 객체는 새로운 내용을 담을 수 있게 됩니다.

 

StringBuffer의 변경

StringBuffer는 문자열을 직접 수정할 수 있다

StringBuffer sb = new StringBuffer("abc");
  • StringBuffer 객체 sb를 "abc"로 초기화했습니다.
  • 내부적으로는 char[] 배열에 a, b, c가 들어가 있으며,
  • 배열의 크기는 기본 생성자의 특성상 여유 공간을 갖고 생성됩니다.

 

문자열 추가 (append())

sb.append("123");
  • 문자열 "123"을 기존 "abc" 뒤에 연결(append) 합니다.
  • StringBuffer는 내부 배열에 이 내용을 추가하기 때문에 기존 객체의 주소는 그대로입니다.
  • 결과적으로 sb는 "abc123"이 됩니다.

 

연속적인 append 사용

StringBuffer sb2 = sb.append("ZZ");
sb.append("ZZ"); 
sb2 = sb; // 같은 객체를 참조
  • append()는 StringBuffer 자기 자신을 반환하기 때문에, 위 코드는 다음과 같습니다:
  • 그래서 sb2도 "abc123ZZ"이 되고, sb와 sb2는 동일한 객체를 가리키는 것입니다.

 

 

중요한 요약

  • StringBuffer는 내부 내용을 직접 바꾸므로 append() 해도 새로운 객체를 만들지 않습니다.
  • 따라서 메서드 체이닝이 가능하며, 아래처럼 한 줄로 이어붙일 수 있습니다:
 
new StringBuffer("abc").append("123").append("ZZ");

 

StringBuffer의 비교

equals() 비교 (객체 비교)

StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");

System.out.println(sb.equals(sb2)); // false
  • StringBuffer 클래스는 equals()를 재정의(override) 하지 않았기 때문에,
  • Object의 기본 equals() 메서드가 호출되어 주소 비교가 일어납니다.
  • 따라서 내용이 같아도 주소가 다르면 false가 됩니다.

toString() 후 문자열 비교

String s = sb.toString();
String s2 = sb2.toString();

System.out.println(s.equals(s2)); // true
  • toString()을 호출하면 StringBuffer가 가지고 있는 문자열을 String으로 변환합니다.
  • String 클래스는 equals()가 문자열의 내용을 비교하므로, "abc" == "abc" → true.

예제

StringBuffer sb = new StringBuffer("abc");
StringBuffer sb2 = new StringBuffer("abc");

System.out.println("sb == sb2 ? " + (sb == sb2));           // false (주소 다름)
System.out.println("sb.equals(sb2) ? " + sb.equals(sb2));   // false (equals는 주소 비교)

String s = sb.toString();
String s2 = sb2.toString();

System.out.println("s.equals(s2) ? " + s.equals(s2));       // true (내용 비교)

 

 

정리

비교 방식 클래스 결과
== StringBuffer 주소 비교 → false
equals() StringBuffer 주소 비교 → false
toString().equals() String 문자열 내용 비교 → true

'Java' 카테고리의 다른 글

오토박싱 & 언박싱  (0) 2025.06.22
래퍼(wrapper) 클래스  (0) 2025.06.22
문자열과 기본형 간의 변  (0) 2025.06.22
String클래스  (0) 2025.06.22
Object클래스 메서드 - toString()  (0) 2025.06.22