ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • String vs StringBuilder vs StringBuffer 이해하기!!
    Java 2018. 8. 30. 01:26
    반응형


    오랜만에 자바와 관련된 주제로 블로그에 글을 쓰네요.. ㅜㅜ

    한 친구가 String과 StringBuilder에 차이를 묻는데

    선뜻 쉽게 이야기하지 못하였던 저를 반성하며, 공부 후 블로그에 정리합니다. ^^








    1. String

      1) Heap 내의 문자열 상수(literal pool) 영역에 저장합니다.

      2) 동일한 문자열을 한번 생성하고, 여러 곳에서 공유해서 사용할 수 있습니다. 

           그렇기 때문에 같은 문자열이 여러번 사용될 때 메모리 효율성이 높습니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class TestString {
        public static void main(String[] args) {    
            String str = "서울특별시";
            String str2 = "서울특별시";
            char data[] = {'서''울''특''별''시'};
            String str3 = new String(data);
            
            System.out.println("str = " + Integer.toHexString(str.hashCode()));
            System.out.println("str2 = " + Integer.toHexString(str2.hashCode()));
            System.out.println("str3 = " + Integer.toHexString(str2.hashCode()));
            System.out.println(str.equals(str2));
            System.out.println(str2.equals(str3));
        }
    }
     
    cs

      ※ 결과화면

          ▶ 위와 같이 String을 생성하면 "서울특별시" 문자열을 Heap 영역내의 문자열 상수 영역에 하나의 문자열로 저장되고, 

              여러 변수에서 참조하는 형식으로 운용됩니다. 


      3) String 객체는 "immutable" 이기 때문에 변경 시 새로 생성합니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class TestString {
        public static void main(String[] args) {    
            String str = "서울특별시";
     
            System.out.println("str = " + Integer.toHexString(str.hashCode()));
            System.out.println("변경된 str = "+Integer.toHexString(str.concat("양재동").hashCode()));
        }
    }
     
    cs

      ※ 결과화면 

          ▶ str뒤 문자열을 추가하여 변경하였을 때 새로운 String 객체가 생성이 된 것을 볼 수 있다.








    2. StringBuilder

      1) Heap영역 내에 저장합니다.

      2) 문자열 변경시 문자열 자체가 변경되기 때문에 문자열이 자주 변경되는 문자열 처리에 적합합니다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class TestStringBuilder {
        public static void main(String[] args) {    
            StringBuilder sb = new StringBuilder("서울특별시");
            System.out.println(sb.append("양재동"));
            System.out.println(sb); 
            String name = "서울특별시양재동";
            System.out.println("sb와 name비교 : "+name.equals(sb.toString()));
     
            StringBuilder sb1 = new StringBuilder("서울특별시");
            StringBuilder sb2 = new StringBuilder("서울특별시");
            System.out.println("sb1와 sb2비교 : "+(sb1==sb2)); 
            System.out.println("sb1와 sb2비교 : "+sb1.equals(sb2));  
        }
    }
     
    cs

        ※ 결과화면 

          ▶ append메소드를 통해 StringBuilder의 내용을 변경하면 sb객체 내용 자체가 변경되는 것을 확인할 수 있습니다.

              또한 같은 문자열의 StringBuilder 객체를 생성하였는데 sb1과 sb2과 다른 객체임을 확인할 수 있습니다.

              * append 내에서는 +를 사용해 문자열을 추가해서 사용하지 않습니다... 


      3) StringBuilder와 StringBuffer에 제공되는 메소드는 동일합니다.

      4) Thread-safe 하지 못합니다.

         ▶ 여러개의 Thread에 하나의 StringBuilder 객체를 처리하면 문제가 발생합니다.








    3. StringBuffer

      1) StringBuilder와 동일합니다.

      2) Thread-safe 합니다.

         ▶ 여러개의 Thread에 하나의 StringBuffer 객체를 처리해도 문제가 발생하지 않습니다.

      







    4. 결론

         ▶ 위의 세가지 클래스 중 String 클래스는 매 번 객체를 생성하여 연산을 하기 때문에 응답시간에 가장 많은 영향을 주고,

             가장 많은 메모리를 차지합니다.

             WAS 를 사용한다면 컴파일러에서 자동으로 StringBuilder로 변환하여 연산합니다.

             하지만 반복문을 통한 문자열 연산은 마찬가지로 매 번 객체를 생성하고 연산합니다.

             그렇기 때문에 StringBuilder를 추천하고, Thread와 관련이 있다면 StringBuffer의 사용을 추천드립니다.

    반응형
Designed by Tistory.