본문 바로가기

Backend/Java

[JAVA] String, StringBuffer, StringBuilder 의 차이점

728x90

이번 주제는 자주 사용하는 클래스인 String, StringBuffer 그리고 익숙하지는 않지만 중요한 StringBuilder 클래스에 대해서 알아보고자 한다. 

 

| String

 

Java 코딩을 하다보면, String 클래스를 사용하는데 문자열을 추가하고 할때 

 

String s1 ="text" + " good"'; 

이런식으로 "+" 연산자를 이용하여 문자열을 더한다. 

하지만 메모리를 효율적으로 사용하고자 할때, 고민을 하고 사용해야 한다. 

 

그 이유를 설명하자면 다음과 같다. 

 

이렇게 코딩이 되어있다면 당연히 결과는 "안녕하세요 반가워요"라고 콘솔에 출력할 것이다. 그렇다면 메모리구조는 어떻게 될까?

public class Main {
	public static void main(String[] args) {
		String str = new String();
		str+= "안녕하세요 ";
		str+= "반가워요";
		System.out.println(str);
	}
}

메모리

스택 영역에 str이 주소값이 생기고 그거에 참조하는 부분이 heap영역에 생기는데 처음에 100번지 주소에 생긴다고 생각해보자. String str = new String(); 부분에서 생기는 것이다.

그리고 다음 줄 str+= "안녕하세요 "; 에서 초록색 안녕하세요로 주소값이 바뀐다. 그러면서 처음에 있었던 100번지 주소값에 대한 참조가 끊기게 된다. 

 

다음줄 str+= "반가워요"; 에서 빨간색부분 "반가워요" 라는 값이 생기면서 str은 앞에 "안녕하세요" 와 "반가워요" 가 합쳐진 500번지 에 있는 메모리값을 참조하게 된다. 그리고 다른 모든 값에 대해서는 참조가 끊기게 된다. 

 

메모리 상으로 볼때도, 좋지 않은것을 한 눈에 알 수 있다. "안녕하세요 반가워요"라는 str값을 만들기 위해 쓸데 없는 메모리가 많이 쌓이게 되었다. 이런 것들이 많이 발생하게 되면 문제가 발생할 것으로 보인다.

즉 heap영역에 가비지 컬렉션이 작동하기 전까지 메모리가 계속 쌓이기 때문에 다른 방법을 쓰는 것이 효과적으로 보인다.


| StringBuffer

 

String 객체는 이렇게 편집되지 않는 특징이 있기 때문에 메모리상 문제가 생기는 것을 알았다. 

메모리를 효율적으로 사용하기 위해서 문자열의 변경이 자주 일어나는 경우 "StringBuffer" 클래스를 사용하도록 하자. 

 

StringBuffer의 특징

1) String 과 다르게  주소가 안바뀐다.

2) 내부적으로 직접 변경이 가능하다.

3) 문자열 변경이 자주 일어나는 경우 사용하면 좋다.

 

public class Main {
	public static void main(String[] args) {
		String stringValue1 = "TEST 1";
		String stringValue2 = "TEST 2";

		System.out.println("stringValue1: " + stringValue1.hashCode());
		System.out.println("stringValue2: " + stringValue2.hashCode());

		stringValue1 = stringValue1 + stringValue2;
		System.out.println("stringValue1: " + stringValue1.hashCode());

		StringBuffer sb = new StringBuffer();

		System.out.println("sb: " + sb.hashCode());

		sb.append("TEST StringBuffer");
		System.out.println("sb: " + sb.hashCode());
	}
}
/*
  실행결과
  stringValue1: -1823841245
  stringValue2: -1823841244
  stringValue1: 833872391
  sb: 664740647
  sb: 664740647
*/

위 코드를 보면 String 클래스는 메모리가 변경이 되지만, StringBuffer클래스를 이용한 경우 주소가 변경되지 않은 것을 알 수 있다. 

 


| StringBuffer  vs  StringBuilder

 

StringBuilder클래스도 마찬가지로 String과 문자열을 더할 때 새로운 객체를 생성하는 것이 아니라 기존의 데이터에 추가하는 방식을 사용하기 떄문에 메모리관리에서 String 보다 좋다. StringBuilder 도 마찬가지로 append()메서드를 이용하여 문자열을 추가한다. 

 

그렇다면, StringBuffer와 StringBuilder의 차이는 무엇일까? 

그 차이를 보기 위해서 Java PlatForm Se 8를 참고하여 API를 살펴보자.

 

* Class StringBuffer

 

A thread-safe, mutable sequence of characters. A string buffer is like a String, but can be modified. At any point in time it contains some particular sequence of characters, but the length and content of the sequence can be changed through certain method calls.

 

String buffers are safe for use by multiple threads. The methods are synchronized where necessary so that all the operations on any particular instance behave as if they occur in some serial order that is consistent with the order of the method calls made by each of the individual threads involved.

 

 

* Class StringBuilder

 

A mutable sequence of characters. This class provides an API compatible with StringBuffer, but with no guarantee of synchronization. This class is designed for use as a drop-in replacement for StringBuffer in places where the string buffer was being used by a single thread (as is generally the case). Where possible, it is recommended that this class be used in preference to StringBuffer as it will be faster under most implementations.

 

StringBuffer에서는  "thread-safe"하다고 나와있다. 하지만 StringBuilder에서는 "no guarantee of synchronization" 이라고 나온다. 즉 두 클래스의 차이는 멀티스레드 환경에서 안정성의 차이이다. StringBuffer는 멀티스레드 환경에서 안정적이고, StringBuilder는 멀티스레드 환경에서 동기화를 보장하지 못한다. 하지만 StringBuilder 클래스는 단일 쓰레드 환경에서 성능은 StringBuffer 보다 뛰어난 것을 알 수 있다. 


# 결론 

 

StirngBuffer, StringBuilder 모두 주소값을 변경하지 않고 문자열을 추가제거 할 수 있으므로 문자열 변경이 잦은 환경에서 String보다는 이 둘 클래스를 사용하는 것이 효율적이다. 또한 멀티스레드 환경에서 StringBuffer는 StringBuilder보다 안정적이므로 StringBuffer 쓰는 것이 좋아 보인다. 하지만 , StringBuffer가 StringBuilder보다 느리기 때문에 단일쓰레드 환경에서는 StringBuilder를 사용하는것이 효율적이다. 

 

StringBuffer    :  문자열 연산이 많고 멀티쓰레드 환경에서 동기화가 필요한 경우 (web, 소켓환경...)

StringBuilder   :  문자열 연산이 많고 단일쓰레드이거나 동기화가 필요없는 환경인 경우  



 

 

 

# 참고자료

 

docs.oracle.com/javase/8/docs/api/

 

Java Platform SE 8

 

docs.oracle.com

javahungry.blogspot.com/2013/06/difference-between-string-stringbuilder.html

 

Difference Between String , StringBuilder and StringBuffer Classes with Example : Java | Java Hungry

 

javahungry.blogspot.com

 

 

 

728x90