[Java] String, StringBuilder, StringBuffer란 뭘까?

코박·2022년 8월 7일
0

JAVA

목록 보기
4/4

String 과 StringBuilder/StringBuffer 의 차이?

String

Immutable

  • String 객체는 한번 값이 할당되면 해당 공간이 변하지 않는 불변성을 가짐
  • String 타입 값 할당 방식은 두가지가 있음
    - String A = "안녕"; [literal]
    • String B = new String("안녕") [new]

그럼 이 차이점을 두고 간단한 테스트를 한번 해보자

ex)

String str = "안녕";
String string = new String("안녕");

System.out.println("Literal 안녕 삽입 후, str address: " + str.hashCode());
System.out.println("New안녕 삽입 후, string address: " + string.hashCode());
System.out.println("두 문자열 비교: " + str == string);

str += "NHN";
System.out.println("NHN 삽입 후, str address: " + str.hashCode());

[결과]

Literal 안녕 삽입 후, str address: 1277839209
New 안녕 삽입 후, string address: 2930001123
두 문자열 비교: false

NHN 삽입 후, str address: 3755200

Q. 왜 두 문자열은 같은데 비교 시 false 를 반환할까?

A. String type 의 값 할당 방식에 따라 저장 방식이 다르기 때문이다.

  • [Literal]
    - 리터럴 방식 사용시 String constant pool이라는 Heap 메모리 영역안의 특별한 메모리 공간에 저장
    - 만약 값 사용 시 String constant pool 안에 존재하는 리터럴 값을 사용하면 메모리 영역에 존재하던 값을 사용
    ex) Literal 타입 선언 한 두 "안녕" 문자열은 비교시 같은 영역에서 사용
  • [New]
    - 일반적으로 사용하는 객체와 동일하게 Heap 메모리 영역안에 저장
    - 그래서 같은 값 사용 시, 동일한 영역에서 가져오는 것이 아님
    ex) New 타입 선언 후 두 "안녕" 문자열은 비교시 다른 영역에서 사용

StringBuilder, StringBuffer

Mutable

  • StringBuilder, StringBuffer 객체는 한번 값이 할당되더라도 다시 다른 값이 할당되면 할당된 공간이 변하는 가변성을 가짐
  • 두 클래스 모두 AbstractStringBuilder 라는 추상 클래스를 상속받아 구현

ex)

StringBuilder builder = new StringBuilder();
StringBuffer buffer = new StringBuffer();

builder.append("빌더");
buffer.append("버퍼");

System.out.println("빌더 삽입 후, builder address: " + builder.hashCode());
System.out.println("버퍼 삽입 후, buffer address: " + buffer.hashCode());

builder.append("NHN");
buffer.append("NHN");

System.out.println("스트링 삽입 후, builder address: " + builder.hashCode());
System.out.println("스트링 삽입 후, buffer address: " + buffer.hashCode());

[결과]

빌더 삽입 후, builder address: 1925478856
NHN 삽입 후, builder address: 1925478856

버퍼 삽입 후, buffer address: 434171759
NHN 삽입 후, buffer address: 434171759

AbstractStringBuilder

  • Value 와 Count 를 가지고있음
    - value: 문자열의 값을 저장하는 byte 배열
    - count: 현재 문자열 크기의 값을 가지는 int 형 변수
  • append() 메소드
    - append() 메소드를 통해 문자열 추가 시 추가할 문자열의 길이만큼 저장하는 공간을 넓힘
    - 늘어난 공간에 추가할 문자열을 넣는 방식 (같은 주소 공간을 참조한 채 가변성 O)
    public AbstractStringBuilder append(String str) {
        if (str == null) {
            return appendNull();
        }
        int len = str.length();
        ensureCapacityInternal(count + len);
        putStringAt(count, str);
        count += len;
        return this;
    }

builder/buffer 의 차이

  • 동기화의 지원 여부
    - StringBuilder 같은 경우 동기화 지원 X
    - StringBuffer 같은 경우 동기화 지원 O (멀티 스레드 환경 안전)
  • StringBuffer 는 Synchronized 키워드를 사용함
    - synchronized: 멀티 스레드 환경에서 하나의 자원에 접근 시, 현재 자원을 사용하고 있는 스레드를 제외한 나머지 스레드는 자원에 접근 불가 역할 수행

각각 사용 방식

String

  • 변하지 않는 문자열을 자주 사용하는 경우 String 사용
  • 문자열 수정이 적으며 멀티쓰레드 환경 사용가능

StringBuilder

  • 동기화 X, 속도면에서 성능 ↑
  • 주로 단일 스레드 환경이나 문자열에 대한 수정이 빈번히 발생하는 경우 StringBuilder 사용

StringBuffer

  • 동기화 O, 멀티 스레드 환경에서 안전하게 동작
  • 멀티스레드 환경, 문자열에 대한 수정이 빈번히 발생하는 경우 StringBuffer 사용

(출처 - tuandevnotes.com)

profile
웹 개발자 할래요

0개의 댓글