
자바라는 언어를 하면서 String
클래스를 접하지 않은 사람은 없을 것입니다.
저도 마찬가지로 프로젝트를 진행하며 자바 코드를 작성할 때에는 String을 사용해왔고, 문자열 연산도 String + String 이런식으로 사용해왔습니다.
Java 라는 언어를 제대로 공부해보게 되면서 StringBuffer
클래스와 StringBuilder
클래스에 대해 알게 되었고 간단하게 알아보았을 때에는 그냥 String과의 차이점을 알지 못하고 필요성도 느끼지 못했습니다.
이시간은 함께 String / StringBuffer / StringBuilder 를 비교해보며 그 쓰임을 알아보도록 하겠습니다.
String
자바에서 String을 선언하는 방식에는 두 가지가 있습니다.
// way1
String name = "Stone_hee";
// way2
String name = new String("Stone_hee");
첫 번째 방법처럼 따옴표를 사용해 문자열을 선언한다면, JVM
은 메모리 중 힙 영역 안에 존재하는 String Pool
에서 같은 문자열이 저장되어있는 메모리 주소를 먼저 찾습니다.
다시 말해, JVM은 같은 문자열이라면, 매번 새로운 객체를 생성해 메모리에 저장하는 것이 아닌, 메모리 주소를 재활용하여 메모리를 효율적으로 관리합니다.
그런데 여기서 문자열 객체의 마음대로 바꾸게 된다면 메모리를 재사용하는 구조에 있어서 효율적으로 메모리를 관리하는데에 어려움이 생깁니다. 그래서 자바는 String을 불변 객체로 설정하게 되었습니다.
만약 같은 문자열을 다른 메모리 주소에 생성하여야 한다면 new 생성자를 사용하면 됩니다.
String str1 = "abc";
String str2 = "abc";
boolean isSameMemory = System.identityHashCode(str1) == System.identityHashCode(str2);
System.out.println(isSameMemory);
//결과 : true
String str3 = new String("abc");
isSameMemory = System.identityHashCode(str1) == System.identityHashCode(str3);
System.out.println(isSameMemory);
//결과 : false
위 코드처럼 identityHashCode
메서드를 통해 비교해보면 str1과 str는 같은 객체이고(String pool에 의해 재사용됨!), str1 과 str3은 다른 객체임을 확인할 수 있습니다.
결과적으로 우리가 알게 된 사실은, String은 불변 객체여야 한다는 것입니다.
StringBuffer
위에서 이야기 했다시피 String은 불변 객체이므로 문자열 연산이 수행될 때 마다 계속해서 새로운 문자열이 생성되므로, 메모리에 많은 부하를 가져오게 됩니다.
그래서 자바에서는 문자열 조작을 쉽고 안정적으로 하기 위해 StringBuffer라는 클래스를 제공하기 시작했습니다.
append(), insert(), concat() 등의 메서드로 메모리를 효율적으로 관리하면서 문자열을 조작할 수 있습니다.
또한 StringBuffer 클래스는 스레드 안정성을 보장하기 때문에, 멀티 스레드 환경에서 사용하기에도 용이합니다.
StringBuilder
StringBuffer 클래스에는 단점 또한 존재합니다. 바로 모든 공용 메서드가 동기화되고, 스레드 안정성을 보장하기 위한 작업들이 성능에 영향을 준다는 것이었습니다.
그래서 자바는 1.5 이상의 버전 부터 스레드 안정성은 낮지만 메서드 동기화 문제가 해결된 클래스인 StringBuilder 클래스가 제공됩니다.
StringBuilder 클래스는 StringBuffer 보다 성능이 좋기 때문에 단일 스레드에서의 작업에서는 StringBuilder를 사용하는 것이 좋습니다. 또 두 클래스의 차이가 있다면 StringBuffer 클래스는 StringBuilder보다 더 많은 내장 메서드를 제공합니다. 하지만 이 경우는 String으로 변환하면 해결되는 문제로 큰 차이는 없습니다.
String vs StringBuffer vs StringBuilder
결론적으로 StringBuffer와 StringBuilder 모두 불변 객체인 String의 단점을 상쇄시키는 가변 객체입니다.
현재 자바에서는 문자열 + 문자열 연산을 진행하면 내부적으로 StringBuffer 혹은 StringBuilder가 사용되므로 간단한 문자열 연산에서는 크게 신경쓰지 않아도 될 지 모릅니다.
하지만 복잡한 문자열 연산 처리 과정에서는 실행 환경에 따라 StringBuffer / StringBuilder를 잘 사용할 줄 알아야겠죠?!
'Language > Java ☕️' 카테고리의 다른 글
자바의 static (0) | 2024.05.22 |
---|---|
자바의 메모리 구조 (0) | 2024.05.22 |
자바의 가비지 컬렉션 (0) | 2024.02.02 |
Double과 Float를 사용하면 안되는 이유 (0) | 2024.02.01 |
JDK vs JRE vs JVM (0) | 2024.02.01 |
안녕하세요, 저는 주니어 개발자 박석희 입니다. 언제든 하단 연락처로 연락주세요 😆