IT

[Java] String, StringBuffer, StringBuilder 차이

data-cloud 2025. 1. 20. 22:02
반응형

 

 

 

☕️ String, StringBuffer, StringBuilder 정의

  • String
    - StringBuffer, StringBuilder 와의 가장 큰 차이점은 String은 불변(immutable)의 속성을 갖는다는 점이다.
    - String 클래스를 통해 변경 연산을 자주 사용할 경우, 힙 메모리에 많은 가비지(Garbage)가 생성되어 힙 메모리 부족으로 이어질 수 있다.
    - String도 불변성을 가지기 때문에 멀티스레드 환경에서의 thread-safe 하다.
    - JDK 1.5 버전 이후부터, String의 + 연산은 컴파일 시에 StringBuilder를 사용하도록 자동변환되어 성능 최적화가 이뤄진다. (단, 항상 변환되는 것은 아니므로 상황에 따라서 StringBuffer 혹은 StringBuilder를 알맞게 사용하는 것이 바람직하다.)

  • StringBuffer
    - String 클래스와 다르게 가변성을 갖는다.
    - 동기화를 지원하여 멀티 스레드 환경에서도 안전하게 동작할 수 있다.

  • StringBuilder
    - String 클래스와 다르게 가변성을 갖는다.
    - 동기화를 지원하지 않는다.

 

 

☕️ String ↔️ StringBuffer, StringBuilder

String 클래스와 StringBuffer, StringBuilder의 가장 큰 차이점은 불변(immutable)성이다.
String은 immutable(불변)하며, StringBuffer 및 StringBuilder는 mutable(변함)하다.
다음의 코드와 같이 각 각의 클래스들의 '연산 전 주소'와 '연산 후 주소'를 비교해 보면, String 클래스의 경우에만 다른 것을 확인할 수 있다.

public static void main(String[] args) {
        
        /* String 클래스의 주소값 테스트 */
        String str = "ABCD";
        System.out.println("[String] 연산 전 주소 : " + str.hashCode());
        str += "EFG";
        System.out.println("[String] 연산 후 주소 : " + str.hashCode());


        /* StringBuffer 클래스의 주소값 테스트 */
        StringBuffer buffer = new StringBuffer("ABCD");
        System.out.println("[StringBuffer] 연산 전 주소 : " + buffer.hashCode());
        buffer.append("EFG");
        System.out.println("[StringBuffer] 연산 후 주소 : " + buffer.hashCode());


        /* StringBuilder 클래스의 주소값 테스트 */
        StringBuilder builder = new StringBuilder("ABCD");
        System.out.println("[StringBuilder] 연산 전 주소 : " + builder.hashCode());
        buffer.append("EFG");
        System.out.println("[StringBuilder] 연산 후 주소 : " + builder.hashCode());

    }

 

 

반응형

 

 

☕️ new String()

String에 값을 할당하는 방법은 다음과 같이 두 가지 방식이 있다.

  • String str = "Hello";
  • String str = new String("Hello");

두 가지 방식을 사용하여 주소 값을 비교해 보자.

public static void main(String[] args) {

        /* String 클래스의 주소값 테스트 */
        String str1 = "Hello";
        String str2 = "Hello";
        String str3 = new String("Hello");
        String str4 = new String("Hello");

        System.out.println("str1 == str2 : " + (str1 == str2));
        System.out.println("str2 == str3 : " + (str2 == str3));
        System.out.println("str3 == str4 : " + (str3 == str4));

    }

동일한 값인 "Hello"가 대입되었는데 왜 이러한 차이가 발생하는 것일까?
답은 저장 방식의 차이 때문이다.

String 객체에 리터럴 값으로 할당(= str1, str2)하는 경우, 값은 Heap 메모리 영역 안의 특수한 공간인 String Constant Pool에 저장된다. 만약 이 Pool에 존재하는 값을 사용할 경우, 새로 리터럴 값을 만드는 것이 아닌 기존의 값을 사용하기 때문에 'str1 == str2'의 계산식이 true가 나올 수 있는 것이다.

결과적으로 메모리 영역에서의 저장 결과는 아래와 같다.

 

 

 

 

References.

1. IfUWanna - [Java] String, StringBuffer, StringBuilder 차이 및 장단점
2. 길은 가면, 뒤에 있다. - [자바] String, StringBuilder, StringBuffer의 차이
3. heoseungyeon.log - StringBuilder와 StringBuffer는 무슨 차이가 있는가?

 

반응형