JAVA:: String과 StringBuilder, StringBuffer의 차이점과 장단점

류영준·2022년 4월 8일
1

JAVA

목록 보기
5/9
post-thumbnail

Java 문자열 대표 클래스

  • Java에서 문자열을 다루는 대표적인 클래스는 String, StringBuilder, StringBuffer 가 있다.

String vs StringBuilder, StringBuffer

  • String과 StringBuilder, StringBuffer 클래스의 가장 큰 차이점은 String은 불변(Immutable)의 속성을 갖는다는 점이다.
  • String 객체는 한 번 값이 할당되면 그 공간은 변하지 않는다.
  • StringBuilder과 StringBuffer 객체는 한 번 값이 할당되더라도 한 번 더 다른 값이 할당되면 할당된 공간이 변하는 특성을 갖고 있다.
  • 여기서 할당된 공간이 변하지 않는 특성을 불변(Immutable), 할당된 공간이 변하는 특성을 가변(mutable)라고 한다.
    • mutable : 문자열 변경시 새로운 메모리 변경 필요 없이 변경 가능

String

String str = "hello"; // String str = new String("hello");
str = str + " world"; // [ hello world ]
  • “hello” 값이 들어가있던 String 클래스의 참조 변수 str이 “hello world”라는 값을 가지고 있는 새로운 메모리영역을 가리키게 변경된다.
  • 처음 선언했던 “hello”로 값이 할당되어 있던 메모리 영역은 Garbage로 남아있다가 GC(Garbage Collection)에 의해 사라진다.
  • String 클래스는 불변하기 때문에 문자열을 수정하는 시점에 새로운 String 인스턴스가 생성된 것이다.
  • 이와 같이 문자열 추가, 수정, 삭제 등의 연산이 빈번하게 발생하는 알고리즘에 String을 사용하면 Heap 메모리에 많은 임시 가비지가 생성되어 힙메모리가 부족으로 애플리케이션 성능에 치명적인 영향을 끼칠게 된다.
  • 따라서 문자열의 추가,수정,삭제가 빈번하게 발생할 경우라면 String 클래스가 아StringBuffer/StringBuilder를 사용해야한다.

StringBuilder, StringBuffer

예제 코드

void stringClassTest() {
        String str = "hello";
        StringBuilder sbd = new StringBuilder();
        StringBuffer sbf = new StringBuffer();

        sbd.append("hello");
        sbf.append("hello");

        System.out.println("String 객체의 주소 = " + str.hashCode());
        System.out.println("StringBuilder 객체의 주소 = " + sbd.hashCode());
        System.out.println("StringBuffer 객체의 주소 = " + sbf.hashCode());

        str += "world";
        sbd.append("world");
        sbf.append("world");

        System.out.println("String 객체의 주소 = " + str.hashCode());
        System.out.println("StringBuilder 객체의 주소 = " + sbd.hashCode());
        System.out.println("StringBuffer 객체의 주소 = " + sbf.hashCode());
    }

실행 결과

  • String, StringBuilder, StringBuffer 타입의 변수를 선언하고 문자열 수정 전과 수정 후의 hashcode() 반환값을 출력해보았다.
    • hashcode() : 각 객체의 주소값을 변환하여 생성한 객체의 고유한 정수값을 반환한다. 두 객체가 동일 객체인지 비교할 때 사용한다.

StringBuilder vs StringBuffer

공통점

  • 공통점은 StringBuilder와 StringBuffer클래스의 공통점은 둘다 mutable한 성질을 가지고 있다는 것이다.

  • 위의 이미지처럼 두 클래스 모두 AbstractStringBuilder 라는 추상 클래스를 상속받아 구현되어 있기 때문에 mutable한 성질을 가지고 있다.
  • AbstractStringBuilder 추상 클래스의 멤버 변수엔 다음 2가지 변수가 존재한다.
    • value : 문자열의 값을 저장하는 byte 배열
    • count : 현재 문자열 크기의 값을 가지는 int형 변수

append()

public AbstractStringBuilder append(String str) {
        if (str == null) {
            return appendNull();
        }
        int len = str.length();
        ensureCapacityInternal(count + len);
        putStringAt(count, str);
        count += len;
        return this;
}
  • StringBuilder와 StringBuffer 클래스의 문자열을 수정하고 싶으면 append() 메서드를 사용한다.
  • StringBuilder , StringBuffer에 문자열을 추가하게 되면 추가할 문자열의 크기(길이)만큼 현재의 문자열을 저장하는 배열의 공간을 늘려주고, 늘려준 공간에 추가할 문자열을 넣어주는 방식으로 되어있다.
  • 위에서 살펴본 내부동작을 통해 값이 변경되더라도 같은 주소공간을 참조하게 되는 것이며, 값이 변경되는 가변성을 띄게 되는 것입니다.

차이점

  • 차이점은 동기화(Synchronization)이다.
  • StringBuilder는 동기화를 지원하지 않는 반면, StringBuffer는 동기화를 지원하여 멀티 스레드 환경에서도 동작할 수 있다.
    • 그 이유는 StringBuffer는 메서드에서 synchronized 키워드를 사용한다.
  • StringBuilder는 싱글 스레드 환경에 적합하고 동기화를 고려하지 않아도 되는 스레드가 안전한 프로그램 개발시 사용한다.
  • StringBuffer은 멀티 스레드 환경에 적합하고 연산이 많을 경우 유리하다.
  • 추가로 StringBuilder은 동기화를 지원하지 않는 반면, 속도면에서는 StringBuffer보다 성능이 좋다.

Java에서의 synchronized 키워드

  • Java에서 synchronized 키워드는 여러 개의 스레드가 한 개의 자원에 접근할려고 할 때, 현재 데이터를 사용하고 있는 스레드를 제외하고 나머지 스레드들이 데이터에 접근할 수 없도록 막는 역할을 수행한다.
  • ex) 멀티스레드 환경에서 A 스레드와 B 스레드가 모두 같은 StringBuffer 클래스 객체 sb의 append() 메서드를 사용하려고 하면, 다음과 같은 절차를 수행한다.
    1. A 스레드 : sb의 append() 동기화 블록에 접근 및 실행
    2. B 스레드 : A 스레드 sb의 append() 동기화 블록에 들어가지 못하고 block 상태가 된다.
    3. A 스레드 : sb의 append() 동기화 블록에서 탈출
    4. B 스레드 : block에서 running 상태가 되며 sb의 append() 동기화 블록에 접근 및 실행

String, StringBuilder, StringBuffer 사용

String을 사용하는 경우

  • 문자열 연산이 적고 멀티쓰레드 환경일 경우

StringBuilder을 사용하는 경우

  • 문자열 연산이 많은 경우
  • 싱글 스레드 환경
  • 동기화를 고려하지 않아도 되는 스레드가 안전한 프로그램 개발시 사용

StringBuffer을 사용하는 경우

  • 문자열 연산이 많은 경우
  • 멀티 스레드 환경

참조

https://ifuwanna.tistory.com/221

https://velog.io/@heoseungyeon/StringBuilder와-StringBuffer는-무슨-차이가-있는가

profile
Backend Developer

0개의 댓글