티스토리 뷰

자바에서는 문자열을 처리하기 위해 String이라는 클래스를 제공한다.


문자열을 다 String으로 처리하면 되는데 왜 StringBuffer왜 StringBuilder라는 것을 만들게 되었는지 부터 알아보도록 하겠다.


 String test = "abcd";


단순한 test라는 변수를 abcd라는 문자열을 포함시켜 생성하였다.


jvm이 가지고 있는 힙 영역에 abcd라는 내용을 가진 영역이 선언되었다.


여기서 "e", "f", "g", ...와 같이 알파벳 소문자를 test라는 변수에 더하여 완성을 해야한다.


 String test= "abcd";

             test += "e";

test += "f";

test += "g";

...



일반적인 상식으론 힙의 test라는 영역에 e와 f, g, ...이 추가된다고 생각하기 마련이다.


하지만 실제 동작으로 힙 영역에선 abcd, abcde, abcdef, abcdefg, ... 와 같은 변수?들이 선언된다. 


선언된 해당 영역이 gc(gabage collector)에 의해 회수 될 때까지 메모리를 차지하게 됨으로 매우 비효율적이라 할 수 있다. 


웹에서(서블릿과 같은) 데이터베이스에 접근을 하는 어플리케이션을 작성 할 때 쿼리문을 String으로 작성하고 프론트에서 넘어오는 값을 토대로 sql 로직을 작성하게 되는 경우 이는 매우 잘못된 설계라 할 수 있다.

(+연산을 통한 문자열 추가 시 객체는 매번 생성된다 - 가 포인트)


이러한 문제점을 해결하기 위해 StringBuilder와 StringBuffer가 탄생하게 되었다.


StringBuilder sb = new StringBuilder();

sb.append("abcd");

sb.append("e");

sb.append("f");

sb.append("g");


위의 코드와 같이 StringBuilder를 사용한다면 메모리상에서 sb라는 빌더의 주소값을 할당 한 후 거기에 append의 인자로 들어오는 값을 붙이는 형태로 실행된다.


Builder를 예로 들었는데 StringBuffer의 사용법 또한 동일하다. 


같은 기능을 하는데 왜 두개인가.


Buffer의 경우 여러 스레드에서 하나의 StringBuffer에 접근할 경우 그 내용에 대해 안전성을 보장한다.(ThreadSafe)


Builder의 경우 단일 스레드에서만 접근을 하는 경우 안전성을 보장하는 차이를 보인다.


StringBuilder의 경우 jdk5.0에 추가된 클래스로 5.0이상의 버전에선 String변수에 추가적으로 +연산을 할 경우 컴파일 단계에서 자동으로 StringBuilder로 변환해 준다고 한다. 


하지만 로직이 문자열을 추가할 시 반복문을 통하는 상황과 같이 컴파일러가 예측하기 힘든 상황은 여전히 객체를 여러번 선언하기 때문에 하나의 문자열 변수에 다른 문자열을 더해야 하는 상황에서는  StringBuilder와 StringBuffer를 적절히 사용하여 구현하는 것이 좋다.





댓글
댓글쓰기 폼