프로그래밍/java 2014. 6. 1. 15:55

1) String, StringBuffer, StringBuilder의 차이점과 쓰임새가 궁금해요. 그리고 성능은 어떤게 좋을까요?

일단 String과 StringBuffer, StringBuilder 둘을 비교할 수 있는데요. 
String은 문자열을 대표하는 것으로 문자열을 조작하는 경우 유용하게 사용할 수 있고요. 
문자열, 숫자, char 등을 concat할 때는 StringBuffer, StringBuilder를 사용할 수 있어요. 단, 복잡한 경우 의미가 있고, 단순한 경우에는 굳이 StringBuffer, StringBuilder를 쓰지 않고 "abc" + 1 + 'd'와 같이 +를 활용해 직접 합쳐도 됩니다.

StringBuffer, StringBuilder는 동기화 지원 여부입니다. 두 클래스가 제공하는 메소드는 같아요. 단, 메소드를 보면 StringBuffer는 각 메소드 별로 synchronized keyword가 존재하죠. 즉, 멀티 쓰레드 상태에서 동기화를 지원한다는 것이 다릅니다. 코드를 보면 다음과 같아요.


  public final class StringBuffer
    public synchronized StringBuffer append(String str) {
        super.append(str);
        return this;
    }

    public synchronized StringBuffer append(boolean b) {
        super.append(b);
        return this;
    }  

    [...]
}


public final class StringBuilder {
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

    public StringBuilder append(boolean b) {
        super.append(b);
        return this;
    }      

    [...]
}

문자열을 +를 활용해 합치는 경우 정확히 어느 버전까지인지 모르겠는데요. 매번 String 인스턴스를 생성하는 방식이였어요. 그래서 성능상의 이슈가 많았죠. 이런 성능 이슈를 개선하기 위해 JDK 1.5 버전 이후에는 컴파일 단계에서 StringBuilder로 컴파일 되도록 변경되었어요. 그래서 JDK 1.5 이후부터는 +를 활용해도 성능상에 큰 이슈는 없습니다.

이 내용을 좀 더 구체적으로 파고 들어 보면 다음과 같아요.


    public String concat1(String start, String end) {
        return start + end;
    }

위 소스 코드를 컴파일 된 바이트 코드 결과물을 확인해 보면 다음과 같이 변경됩니다.


Compiled from "StringConcatenations.java"
public class StringConcatenations {
  public StringConcatenations();
    Code:
       0: aload_0
       1: invokespecial #8                  // Method java/lang/Object."<init>":()V
       4: return

  public java.lang.String concat1(java.lang.String, java.lang.String);
    Code:
       0: new           #16                 // class java/lang/StringBuilder
       3: dup
       4: aload_1
       5: invokestatic  #18                 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
       8: invokespecial #24                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
      11: aload_2
      12: invokevirtual #27                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      15: invokevirtual #31                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      18: areturn

결과적으로 StringBuilder로 변환되는 것을 알 수 있어요. 최근 JDK 버전에서는 굳이 StringBuilder를 쓰지 않아도 되는거죠.


'프로그래밍 > java' 카테고리의 다른 글

java annotaion에 대해서  (0) 2014.06.01
Java Reflection에 대해  (0) 2014.06.01
자바 가비지컬렉션 과정에 관해  (0) 2014.05.31
추상화란..  (0) 2014.04.15
이클립스에서 디버깅  (0) 2013.02.03
//