String클래스는 인스턴스를 생성할 때 지정된 문자열을 변경할 수 없기 때문에 문자열 결합시 계속해서 새로운 인스턴스를 생성한다.
하지만 StringBuffer클래스는 변경이 가능하다!
내부적으로 문자열 편집을 위한 버퍼(buffer)를 가지고 있으며, StringBuffer인스턴스를 생성할 때 그 크기를 지정할 수 있다.
크기를 지정할 때 나중에 편집을 고려하여 버퍼의 길이를 충분히 잡아주는 것이 좋다. 버퍼의 길이를 넘어서게 되면 버퍼의 길이를 늘려주는 작업을 추가적으로 해야 하기 때문이다.
StringBuffer클래스의 인스턴스를 생성하면 동시에 char형 배열이 생성된다. 이 배열은 이후 문자열을 저장하고 편집하기 위한 공간(buffer)로 사용된다.
따라서 StringBuffer클래스의 생성자는 위 char형 배열의 길이를 매개변수로 받게 되어있다.
만약 매개변수로 길이를 지정해주지 않을시 16개의 문자를 저장할 수 있는 크기의 버퍼를 생성한다.
public StringBuffer(int length) {
value = new char[length];
shared = flase;
// 인스턴스 생성시 int값을 넣어주면 해당 길이의 배열생성
}
public StringBuffer() {
this(16);
// 인스턴스 생성시 아무런 값을 넣지 않으면 길이를 16으로 지정
}
public StringBuffer(String str) {
this(str.length() + 16);
append(str);
// 인스턴스 생성시 문자열을 넣으면 해당 문자보다 16 더 크게 버퍼 생성
}
StringBuffer sb = new StringBuffer("abc");
// char[]에 앞에서부터 a,b,c를 저장
sb.append("123");
// 배열에서 a,b,c 뒤에 1,2,3 추가하여 저장
// append()는 반환타입이 StringBuffer인데 자신의 주소를 반환한다.
StringBuffer sb2 = sb.append("가나");
// sb내용 뒤에 가,나를 덧붙인다.
System.out.println(sb); // "abc123가나" 출력
System.out.println(sb2); // "abc123가나" 출력
sb와 sb2 모두 같은 StringBuffer인스턴스를 가리키고 있으므로 같은 내용이 출력된다!
StringBuffer클래스는 String클래스와 다르게 equals메서드가 오버라이딩 되어있지 않아 equals메서드를 사용하여도 등가비교연산자(==)로 비교한 것과 같은 결과를 얻는다.
String sb1 = new StringBuffer("abc");
String sb2 = new StringBuffer("abc");
System.out.println(sb==sb2); // false
System.out.println(sb.equals(sb2); // false
반면에 toString( )은 오버라이딩이 되어 있기 때문에 StringBuffer인스턴스를 String으로 바꿀 수 있다.
이렇게 String으로 바꾸어준 후 equals메서드를 사용하면 비교 가능하다.
String s1 = sb1.toString()
String s2 = sb2.toString()
System.out.println(s.equals(s2)); // true
🔥 한줄평
프로그래머스를 풀다가 접해본 적이 있는데 String과의 차이를 알지못해서 궁금했던 기억이 있다!
변경이 가능한 String클래스 => StringBuffer클래스!