StringBuffer클래스

정순동·2023년 12월 12일
0

자바기초

목록 보기
48/89

String클래스는 인스턴스를 생성하고 지정된 문자열을 변경할 수 없지만 StringBuffer클래스는 변경이 가능하다. 내부적으로 문자열 편집을 위한 버퍼(buffer)를 가지고 있으며, StringBuffer인스턴스를 생성할 때 그 크기를 지정할 수 있다. 이 때, 편집할 문자열의 길이를 고려하여 버퍼의 길이를 충분히 잡아줘야 한다. 만약 편집중에 버퍼의 길이를 넘어서면 버퍼의 길이를 늘려주는 작업이 추가되어 성능 하락이 발생하기 때문이다.
StringBuffer는 String클래스와 유사하며 아래처럼 char형 배열이 존재한다

	public final class StringBuffer implements java.io.Serializable {
    	private char[] value;
        ...
    }

StringBuffer의 생성자

StringBuffer인스턴스를 생성하면, 적절한 길이의 char형 배열이 생성되고, 이 배열은 문자열을 저장하고 편집하기 위한 공간인 버퍼(buffer)로 사용된다.
StringBuffer의 기본 생성자는 버퍼크기가 16인 인스턴스를, StringBuffer(String str) 생성자는 str.length + 16크기의 버퍼를 가진 인스턴스를 생성한다.

	public StringBuffer(int length) {
    	value = new char[length];
        shared = false;
    }
    
    public StringBuffer() {
    	this(16); // 기본 생성자로 인스턴스 생성시 위 StringBuffer(int 16)생성자 호출
    }
    
    public StringBuffer(String str) {
    	this(str.length() + 16);
        append(str);
    }

아래는 StringBuffer클래스의 일부이며 버퍼의 크기가 모자랄 때 현재 배열의 크기보다 더 큰 배열을 만들고, 복사하여 사용하는 과정이다.

	// 새로운 길이(newCapacity)의 배열 생성
    char newValue[] = new char[newCapacity];
    
    // 배열 value의 내용을 배열 newValue로 복사한다.
    System.arraycopy(value, 0, newValue, 0, count); // count는 문자열의 길이
    value = newValue; // 새로 생성된 배열의 주소를 참조변수 value에 저장

StringBuffer의 변경

String과 달리 StringBuffer는 내용 변경이 가능하다.

	public class Test {
    	public static void main(String[] args) {
        	StringBuffer sb = new StringBuffer("abc");
        	System.out.println(System.identityHashCode(sb));
        	sb.append("123");
        	System.out.println(System.identityHashCode(sb));
    	}
	}

위 코드의 실행 결과

	1784662007
	1784662007

서로 주소값이 같은것을 알 수 있다. String클래스에서는 추가하면 주소값이 다르게 나왔었다.

참고로 append()는 반환타입이 StringBuffer인 자신의 주소를 반환한다. 따라서 아래 코드에서 sb과 sb2는 같은 객체다.

	StringBuffer sb2 = sb.append("ZZ"); // sb의 내용뒤에 "ZZ"를 추가한다
    System.out.println(sb); // abc123ZZ
    System.out.println(sb2); //  abc123ZZ

StringBuffer의 비교

StringBuffer클래스의 equals() 메서드는 object클래스의 equals()메서드와 같다. String클래스 처럼 오버라이딩 하지 않았다는 소리이다. 따라서 equals()나 ==나 같은 결과를 나타낸다.

	StringBuffer sb = new StringBuffer("abc");
    StringBuffer sb2 = new StringBuffer("abc");
    
    System.out.println(sb==sb2);		// false
    System.out.println(sb.equals(s2));	// false

다만 toString()은 오버라이딩이 되어, 사용하게 되면 담고있는 문자열을 String으로 반환 해 주기에 비교하려면 toString.equals()를 사용하여 String클래스의 equals를 사용하면 되겠다.

StringBuffer는 멀티쓰레드에 안전하도록 동기화 되어 있으므로 StringBuffer의 성능을 동기화가 저하시킨다. 따라서 멀티쓰레드로 작성된 프로그램이 아닌 경우에는 StringBuffer의 동기화는 매우 불필요하다. 이런 경우에는 쓰레드의 동기화만 뺀 StringBuilder를 사용하면 좋다.
StringBuffer도 충분히 성능이 괜찮기에 성능향상이 반드시 필요하지 않는다면 굳이 바꿀 필요는 없다.

0개의 댓글